summaryrefslogtreecommitdiffstats
path: root/languages/ada/adasupport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'languages/ada/adasupport.cpp')
-rw-r--r--languages/ada/adasupport.cpp168
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, "/="));
+}
+