diff options
Diffstat (limited to 'languages/ada/adasupport.cpp')
-rw-r--r-- | languages/ada/adasupport.cpp | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/languages/ada/adasupport.cpp b/languages/ada/adasupport.cpp new file mode 100644 index 00000000..6b877b7b --- /dev/null +++ b/languages/ada/adasupport.cpp @@ -0,0 +1,168 @@ +#include <ctype.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <stack> +#include <string> +#include <antlr/AST.hpp> +#include "AdaParser.hpp" +#include "AdaTokenTypes.hpp" +#include "adasupport.hpp" + +#define eq !strcmp + +using namespace std; + +const RefAdaAST AdaAST::nullAdaAST(antlr::nullAST.get() ); + +using namespace std; + +string text (const RefAdaAST& n) +{ + if (n == 0 || n == AdaAST::nullAdaAST) + return ""; + string retval; + int type = n->getType(); + if (type == AdaTokenTypes::DOT) { + const RefAdaAST& sibs = n->down (); + retval = text (sibs); + retval.append ("."); + retval.append (text (sibs->right())); + } else { + retval = n->getText(); + } + /* + const RefAdaAST& r = n->right(); + if (r != 0 && r->getType () == AdaTokenTypes::DOT) { + retval.append ("."); + retval.append (text (r->right())); + } + */ + return retval; +} + +int txteq (RefAdaAST n1, RefAdaAST n2) +{ + if (!n1 || !n2 || n1 == antlr::nullAST || n2 == antlr::nullAST) + return 0; + const char* s1 = n1->getText().c_str(); + const char* s2 = n2->getText().c_str(); + if (strcasecmp (s1, s2) != 0) + return 0; + n1 = n1->right (); + n2 = n2->right (); + if (!n1 || !n2 || n1 == antlr::nullAST || n2 == antlr::nullAST) + return 1; + if (n1->getType () == AdaTokenTypes::DOT) + if (n2->getType () == AdaTokenTypes::DOT) + return txteq (n1->right (), n2->right ()); + else + return 0; + else if (n2->getType () == AdaTokenTypes::DOT) + return 0; + return 1; +} + +std::stack<RefAdaAST> defid_stack; + +void AdaParser::push_def_id (const RefAdaAST& defid) +{ +#ifdef __DEBUG__ + string txt (text (defid)); + printf ("push_def_id: pushing %s\n", txt.c_str()); +#endif + defid_stack.push (defid); +} + +const RefAdaAST& AdaParser::pop_def_id () +{ + if (defid_stack.size() == 0) { + fprintf (stderr, "pop_def_id() called on empty stack\n"); + // return static_cast<RefAdaAST>(antlr::nullAST); + return AdaAST::nullAdaAST; + } + RefAdaAST& top = defid_stack.top (); +#ifdef __DEBUG__ + string txt (text (top)); + printf ("pop_def_id: popping %s\n", txt.c_str()); +#endif + defid_stack.pop (); + return top; +} + +bool AdaParser::end_id_matches_def_id (const RefAdaAST& endid) +{ + if (defid_stack.size() == 0) + return false; + RefAdaAST& top = defid_stack.top (); + string defid (text (top)); + defid_stack.pop(); + if (endid == 0 || endid == antlr::nullAST) + return false; + string txt (text (endid)); + if (strcasecmp (defid.c_str (), txt.c_str ()) != 0) { + string errtxt ("End id "); + errtxt.append (txt); + errtxt.append (" does not match "); + errtxt.append (defid); + reportError (errtxt); + return false; + } +#ifdef __DEBUG__ + printf ("end_id_matches_def_id: popped %s\n", txt.c_str()); +#endif + return true; +} + +char * strtolower (char *string) +{ + char *p = string; + if (!p) + return NULL; + while (*p) + { + if (isupper (*p)) + *p = tolower (*p); + p++; + } + return string; +} + +char * extracted_operator (const char *string) +{ + int len = strlen (string); + static char op[10]; + + if (len < 4 && len > 5 || *string != '"' || *(string + len - 1) != '"') + return NULL; + + strcpy (op, string + 1); + op[len - 2] = '\0'; /* discard ending quotation mark */ + strtolower (op); + return op; +} + +bool AdaParser::definable_operator (const char *string) +{ // operator_symbol sans "/=" + char *op = extracted_operator (string); + if (op == NULL) + return false; + return + (eq (op, "=") || + eq (op, "<") || eq (op, ">") || + eq (op, "<=") || eq (op, ">=") || + eq (op, "&") || eq (op, "**") || + eq (op, "*") || eq (op, "/") || eq (op, "+") || eq (op, "-") || + eq (op, "abs") || eq (op, "rem") || eq (op, "mod") || + eq (op, "and") || eq (op, "or") || eq (op, "xor") || eq (op, "not")); +} + +bool AdaParser::is_operator_symbol (const char *string) +{ + char *op; + if (definable_operator (string)) + return true; + op = extracted_operator (string); + return (eq (op, "/=")); +} + |