Added error messages displaying using source file name and line number
[zilutils.git] / zilasm / directives.cpp
diff --git a/zilasm/directives.cpp b/zilasm/directives.cpp
new file mode 100644 (file)
index 0000000..d15ba89
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * directives.c -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016, 2020 Jason Self <j@jxself.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <stdlib.h>            /* bsearch */
+#include <string.h>            /* strcmp */
+#include <stdio.h>
+#include <stack>
+#include <string>
+using namespace std;
+
+#include "header.h"
+#include "parser.h"
+#include "directives.h"
+
+#define ARRAY_SIZE(x)  ((sizeof(x)) / (sizeof(x[0])))
+
+int g_stopParsing = 0;
+stack<FILE*> g_fileHandlers;
+
+
+
+static int
+byte_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+end_handler (const char *args)
+{
+       g_stopParsing = 1;
+       return 0;
+}
+
+static int
+endi_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+endt_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+fstr_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+funct_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+gstr_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+gvar_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+insert_handler (const char *args)
+{
+       string file_name;
+       char *p = (char*)args;
+       while (*p == ' ') p++;
+
+       if (*p == '"')
+       {
+               p++;
+               do
+               {
+                       file_name += *p;
+                       p++;
+               }
+               while (*p != '"' && *p != 0 ) ;
+       }
+       else
+       {
+               do
+               {
+                       file_name += *p;
+                       p++;
+               } while (*p != ' ' && *p != '\n' && *p != '\r' && *p != '\t' && *p != 0);
+       }
+       
+       if (file_name.find('.') == string::npos)
+       {
+               file_name += ".zap";
+       }
+
+#ifdef WIN32
+       char delimeter = '\\';
+#else
+       char delimeter = '/';
+#endif
+
+       Parsing_Context pc;
+       if (file_name.rfind(delimeter) == string::npos)
+       {
+               pc.current_directory = "";
+               pc.current_file_name = file_name;
+       }
+       else
+       {
+               pc.current_directory = file_name.substr(0, file_name.rfind(delimeter)+1);
+               pc.current_file_name = file_name.substr(file_name.rfind(delimeter)+1);
+       }
+
+       pc.current_directory = g_parsing_contexts.top().current_directory + pc.current_directory;
+       //pc.current_file_name = s;
+       g_parsing_contexts.push(pc);
+       
+       
+       unsigned saveLineNumber = g_currentLineNumber;
+       parse_file(); //s.c_str());
+       g_currentLineNumber = saveLineNumber;
+       return strlen(args);
+}
+
+static int
+len_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+newdirective_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+object_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+prop_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+str_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+strl_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+table_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+vocbeg_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+vocend_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+word_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+static int
+zword_handler (const char *args)
+{
+  /* !!! TODO !!! */
+  return 0;
+}
+
+// Sorted array
+static Directive Directives[] = {
+  "BYTE", byte_handler,
+  "END", end_handler,
+  "ENDI", endi_handler,
+  "ENDT", endt_handler,
+  "FSTR", fstr_handler,
+  "FUNCT", funct_handler,
+  "GSTR", gstr_handler,
+  "GVAR", gvar_handler,
+  "INSERT", insert_handler,
+  "LEN", len_handler,
+  "NEW", newdirective_handler,
+  "OBJECT", object_handler,
+  "PROP", prop_handler,
+  "STR", str_handler,
+  "STRL", strl_handler,
+  "TABLE", table_handler,
+  "VOCBEG", vocbeg_handler,
+  "VOCEND", vocend_handler,
+  "WORD", word_handler,
+  "ZWORD", zword_handler
+};
+
+typedef struct
+{
+  const char *contents;
+  unsigned length;
+} Name;
+
+static int
+namecmp (const void *key, const void *elem)
+{
+  const Name *p = (Name *) key;
+  const Directive *d = (Directive *) elem;
+
+  int len1 = p->length;
+  int len2 = strlen (d->name);
+
+  int rc = memcmp (p->contents, elem, len1 < len2 ? len1 : len2);
+  return rc ? rc : (len1 - len2);
+}
+
+Directive_handler
+directive_lookup (const char *name, unsigned namelen)
+{
+  Name n = { name, namelen };
+  Directive *p =
+    (Directive *) bsearch (&n, Directives, ARRAY_SIZE (Directives),
+                          sizeof (Directive), namecmp);
+  return p ? p->handler : NULL;
+}