Added error messages displaying using source file name and line number
authorJason Self <j@jxself.org>
Sun, 23 Aug 2020 15:36:28 +0000 (08:36 -0700)
committerJason Self <j@jxself.org>
Sun, 23 Aug 2020 15:36:28 +0000 (08:36 -0700)
Added .END and .INSERT directives

zilasm/Makefile.am
zilasm/directives.c [deleted file]
zilasm/directives.cpp [new file with mode: 0644]
zilasm/directives.h
zilasm/main.cpp
zilasm/parser.cpp
zilasm/parser.h
zilasm/string_table.cpp

index 5faa8ef82e4009ab963356bb14d3b4a7a63270d7..06a834be80c0e9d4128579fc9586605b7b3e1570 100644 (file)
@@ -2,7 +2,7 @@
 # Process this file with automake to produce Makefile.in.
 #
 # Copyright (C) 2015 Alexander Andrejevic <theflash AT sdf DOT lonestar DOT org>
-# Copyright (C) 2019 Jason Self <j@jxself.org>
+# Copyright (C) 2019, 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
@@ -21,5 +21,5 @@
 
 bin_PROGRAMS = zilasm
 man_MANS = zilasm.1
-zilasm_SOURCES = main.cpp opcodes.c symtable.c header.cpp parser.cpp directives.c labels.cpp string_table.cpp zmem.c
+zilasm_SOURCES = main.cpp opcodes.c symtable.c header.cpp parser.cpp directives.cpp labels.cpp string_table.cpp zmem.c
 include_HEADERS =       opcodes.h symtable.h header.h parser.h directives.h labels.h string_table.h zmem.h
diff --git a/zilasm/directives.c b/zilasm/directives.c
deleted file mode 100644 (file)
index 7c4eb19..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * directives.c -- part of ZilUtils/ZilAsm
- *
- * Copyright (C) 2016 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 "directives.h"
-
-#define ARRAY_SIZE(x)  ((sizeof(x)) / (sizeof(x[0])))
-
-static int
-byte_handler (const char *args)
-{
-  /* !!! TODO !!! */
-  return 0;
-}
-
-static int
-end_handler (const char *args)
-{
-  /* !!! TODO !!! */
-  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)
-{
-  /* !!! TODO !!! */
-  return 0;
-}
-
-static int
-len_handler (const char *args)
-{
-  /* !!! TODO !!! */
-  return 0;
-}
-
-static int
-new_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", new_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;
-}
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;
+}
index 5988c0a6ae2ffdba5d7d9ba3375fbf8a5df5db18..b1ddd2385b444652b746ac2fec547a712155fa44 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * directives.h -- part of ZilUtils/ZilAsm
  *
- * Copyright (C) 2016 Jason Self <j@jxself.org>
+ * 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
@@ -31,5 +31,7 @@ typedef struct
 } Directive;
 
 Directive_handler directive_lookup (const char *name, unsigned namelen);
+extern int g_stopParsing;
+extern stack<FILE*> g_fileHandlers;
 
 #endif /* ifndef ZILASM_DIRECTIVES */
index 22b7e7145c09d8642fe8df92455ebae9b11d26ec..68846b03da7fb491cf82c6861d67baf59a8bdc8b 100644 (file)
@@ -2,7 +2,7 @@
  * main.c
  *
  * Copyright (C) 2015 Alexander Andrejevic <theflash AT sdf DOT lonestar DOT org>
- * Copyright (C) 2015, 2019 Jason Self <j@jxself.org>
+ * Copyright (C) 2015, 2019, 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
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
+#include <string>
+#include <list>
+#include <stack>
+using namespace std;
+
+
 extern "C"
 {
 #include <strings.h>
@@ -39,9 +45,7 @@ extern "C"
 }
 #include "parser.h"
 
-#include <string>
-#include <list>
-using namespace std;
+
 
 const int DEFAULT_ZVERSION = 6;
 
@@ -143,7 +147,7 @@ CMain::assembly ()
       ++m_code_size;
 
       // write instructions' codes
-      for (int i = 0; i < g_numberOfInstructions; ++i)
+      for (int i = 0; i < g_number_of_instructions; ++i)
        {
          for (int j = 0; j < g_codes[i]->used_size; ++j)
            {
@@ -424,9 +428,33 @@ main (int argc, char *argv[], char *envp[])
 
   init_parser ();
 
-  for (int i = optind; i < argc; i++)
-    parse_file (argv[i]);
-  main.assembly ();
+       //for (int i = optind; i < argc; i++)
+       //      parse_file(argv[i]);
+  
+  string file_name = argv[optind];
+  Parsing_Context pc;
+
+#ifdef WIN32
+  char delimeter = '\\';
+#else
+  char delimeter = '/';
+#endif
+
+  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);
+  }
+  g_parsing_contexts.push(pc);
+
+  parse_file();// argv[optind]);
+  if ( !g_haveErrors )
+       main.assembly ();
 
   /* TODO! List global symbols */
   /* TODO! Find abbreviations */
index 31e257fd444623db965366e8b293d130f8b79032..b819792a14815b07fa6bc4c866a561df6d699f4f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * parser.c -- part of ZilUtils/ZilAsm
  *
- * Copyright (C) 2016, 2019 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019, 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
 #include <string.h>            /* strlen */
 #include <ctype.h>
 #include <string>
+#include <stack>
 using namespace std;
 
 
 #include "header.h"
 #include "parser.h"
+#include "directives.h"
 
 extern "C"
 {
-#include "directives.h"
 #include "opcodes.h"
 }
 #include "labels.h"
@@ -42,21 +43,45 @@ extern "C"
 #define isbindigit(c)  ((c) == '0' || (c) == '1')
 
 /* !!! TODO !!! */
-#define fatal_error(errmsg) printf(errmsg)
+//#define fatal_error(errmsg) printf(errmsg)
 #define PC NULL
 
-unsigned g_numberOfInstructions = 0;
+unsigned g_number_of_instructions = 0;
+
+unsigned g_currentLineNumber = 0;
+//string g_source_directory;
+bool g_haveErrors = false;
+
+stack<Parsing_Context> g_parsing_contexts;
 
 
 ZMemblock (*g_codes[MAX_NUMBER_OF_INSTRUCTIONS]);
 
+string
+build_error_message(const char *message)
+{
+       char buff[300];
+       sprintf(buff, "error at %s%s line %d: %s", g_parsing_contexts.top().current_directory.c_str(),
+               g_parsing_contexts.top().current_file_name.c_str(), g_currentLineNumber, message);
+       return string(buff);
+}
+
+
+void
+fatal_error(const char *errmsg)
+{
+       printf( "%s\n", errmsg);
+       g_haveErrors = true;
+}
+
+
 
 void
 checksep (const char *p)
 {
   if (!*p || iscomment (*p) || isspace (*p))
     return;
-  fatal_error ("wrong chars");
+  fatal_error (build_error_message ("wrong chars").c_str());
 }
 
 
@@ -91,7 +116,7 @@ tryparse_directive (const char *p)
   Directive_handler f = directive_lookup (a, b - a);
   if (!f)
     return 0;
-  return (*f) (b);
+  return (b-a) + (*f) (b);
 }
 
 
@@ -115,7 +140,7 @@ tryparse_label (const char *a, const char *b, const char *c)
     }
   else
     {
-      fatal_error ("wrong label type");
+      fatal_error (build_error_message("wrong label type").c_str());
     }
 
   while (*c++ == ':');
@@ -144,72 +169,96 @@ tryparse_name (const char *a)
 int
 tryparse_instruction (const char *a)
 {
-  const char *b = pass_alnums (a);
-  if (b != a)
-    {
-      int len = b ? b - a : strlen (a);
-      ZOpcode *op = (ZOpcode *) symtable_lookup2 (Opcodes, a, len);
-      if (!op)
-       return 0;
-      ZOpcode_flags flags = op->flags;
-      /* !!! TODO !!! */
-
-
-      ZMemblock *mem_additional = NULL;
-
-      switch (op->opcode)
+       bool display_error = false;
+       int len = 0;
+       const char *b = pass_alnums(a);
+       if (b != a)
        {
-       case Opcode_CRLF:
-       case Opcode_PRINT:
-       case Opcode_QUIT:
-         break;
-
-       case Opcode_PRINTI:
-       case Opcode_PRINTR:
-         {
-           char *p = (char *) a + len;
-           p = (char *) pass_spaces (p);
-           if (*p == '\"')
-             {
-               p++;
-               string str;
-               while (*p != '\"')
-                 {
-                   str += *p;
-                   ++p;
-                 }
-               len = p - a;
-               mem_additional =
-                 String_table::encrypt_string (str.c_str (), NULL);
-             }
-           break;
-         }
-       default:
-         fatal_error ("error! instruction not supported");
-         return 0;
+               len = b ? b - a : strlen(a);
+               ZOpcode *op = (ZOpcode *)symtable_lookup2(Opcodes, a, len);
+               if (op)
+               {
+                       ZOpcode_flags flags = op->flags;
+                       ZMemblock *mem_additional = NULL;
+
+                       switch (op->opcode)
+                       {
+                       case Opcode_CRLF:
+                       case Opcode_PRINT:
+                       case Opcode_QUIT:
+                               break;
+
+                       case Opcode_PRINTI:
+                       case Opcode_PRINTR:
+                       {
+                               char *p = (char *)a + len;
+                               p = (char *)pass_spaces(p);
+                               if (*p == '\"')
+                               {
+                                       p++;
+                                       string str;
+                                       while (*p != '\"')
+                                       {
+                                               str += *p;
+                                               ++p;
+                                       }
+                                       len = p - a;
+                                       mem_additional =
+                                               String_table::encrypt_string(str.c_str(), NULL);
+                               }
+                               break;
+                       }
+                       default:
+                       {
+                               display_error = true;
+                       }
+                       }
+
+
+                       if (display_error == false)
+                       {
+
+                               int instruction_size = 1;
+                               if (mem_additional)
+                                       instruction_size += mem_additional->used_size;
+
+                               g_codes[g_number_of_instructions] = zmem_init(instruction_size);
+                               zmem_putbyte(g_codes[g_number_of_instructions], op->opcode);
+
+                               if (mem_additional)
+                               {
+                                       for (int i = 0; i < mem_additional->used_size; ++i)
+                                               zmem_putbyte(g_codes[g_number_of_instructions],
+                                                       mem_additional->contents[i]);
+                                       zmem_destroy(mem_additional);
+                               }
+
+                               ++g_number_of_instructions;
+                               return len;
+                       }
+               }
+               else
+               {
+                       //display_error = true;
+                       string message = "wrong line \"" + string(a) + string("\"");
+                       fatal_error(build_error_message(message.c_str()).c_str());
+               }
        }
 
-      int instruction_size = 1;
-      if (mem_additional)
-       instruction_size += mem_additional->used_size;
-      //printf("instruction %s", a);
-
-      g_codes[g_numberOfInstructions] = zmem_init (instruction_size);
-      zmem_putbyte (g_codes[g_numberOfInstructions], op->opcode);
-
-      if (mem_additional)
+       if (display_error)
        {
-         for (int i = 0; i < mem_additional->used_size; ++i)
-           zmem_putbyte (g_codes[g_numberOfInstructions],
-                         mem_additional->contents[i]);
-         zmem_destroy (mem_additional);
+               char buff[300];
+               if (len == 0)
+                       len = strlen(a);
+               char *instrcution_name = (char *)malloc(len + 1);
+               memcpy(instrcution_name, a, len);
+               instrcution_name[len] = 0;
+               string message = "instruction " + string(instrcution_name) + string(" is not supported yet");
+               fatal_error(build_error_message(message.c_str()).c_str());
+               free(instrcution_name);
        }
 
-      ++g_numberOfInstructions;
-      return len;
-    }
-
-  return 0;
+       return strlen(a);
 }
 
 
@@ -233,7 +282,7 @@ parse_line (const char *p)
        return n;               // ..label or assignment
       if (n = tryparse_instruction (p))
        return n;
-      fatal_error ("wrong line");
+      //fatal_error ("wrong line");
     }
   return 0;
 }
@@ -241,32 +290,49 @@ parse_line (const char *p)
 #define MAX_LINESIZE 1024
 
 int
-parse_file (const char *filename)
+parse_file (/*const char *filename*/)
 {
-  FILE *fp = fopen (filename, "r");
-  if (!fp)
-    fatal_error ("wrong file");
+       if (g_parsing_contexts.size() > 0)
+       {
+               string filename = g_parsing_contexts.top().current_directory + g_parsing_contexts.top().current_file_name;
 
-  //const int MAX_LINESIZE = 1024;
-  char line[MAX_LINESIZE];
-  int newline_missing = 0;
+               FILE *fp = fopen(filename.c_str(), "r");
+               if (fp)
+               {
 
-  while (fgets (line, MAX_LINESIZE, fp))
-    {
-      if (newline_missing)
-       fatal_error ("line too long");
+                       g_currentLineNumber = 0;
 
-      int n = strlen (line);
-      if (!n)
-       continue;
+                       //const int MAX_LINESIZE = 1024;
+                       char line[MAX_LINESIZE];
+                       int newline_missing = 0;
 
-      parse_line (line);
+                       while (g_stopParsing == 0 && fgets(line, MAX_LINESIZE, fp))
+                       {
+                               ++g_currentLineNumber;
 
-      newline_missing = (line[n - 1] != '\n');
-    }
+                               if (newline_missing)
+                                       fatal_error(build_error_message("line too long").c_str());
 
-  fclose (fp);
-  return 0;
+                               int n = strlen(line);
+                               if (!n)
+                                       continue;
+
+                               parse_line(line);
+
+                               newline_missing = (line[n - 1] != '\n');
+                       }
+
+                       fclose(fp);
+               }
+               else
+               {
+                       string message = string("can't open file ") + filename;
+                       fatal_error(message.c_str());
+               }
+
+               g_parsing_contexts.pop();
+       }
+       return 0;
 }
 
 /*
@@ -298,16 +364,19 @@ if (current_token == DIRECTIVE) {
 void
 init_parser ()
 {
-  g_numberOfInstructions = 0;
+  g_number_of_instructions = 0;
 }
 
 
+
+
+
 void
 relase_parser ()
 {
-  for (int i = 0; i < g_numberOfInstructions; ++i)
+  for (int i = 0; i < g_number_of_instructions; ++i)
     {
       zmem_destroy (g_codes[i]);
     }
-  g_numberOfInstructions = 0;
+  g_number_of_instructions = 0;
 }
index 2ed9ae7f0d6d9f840d549df7ccbb95527f911050..007d2ffe48e09817d85b9cd51b283a85a064b185 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * parser.h -- part of ZilUtils/ZilAsm
  *
- * Copyright (C) 2016, 2019 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019, 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
@@ -31,11 +31,21 @@ struct Instruction
 
 void init_parser ();
 
-int parse_file (const char *filename);
+int parse_file();// const char *filename);
 
-extern unsigned g_numberOfInstructions;
+extern unsigned g_number_of_instructions;
 
 #define MAX_NUMBER_OF_INSTRUCTIONS 65536
 extern ZMemblock (*g_codes[MAX_NUMBER_OF_INSTRUCTIONS]);
 
+struct Parsing_Context
+{
+       string current_directory;
+       string current_file_name;
+};
+
+extern stack<Parsing_Context> g_parsing_contexts;
+extern unsigned g_currentLineNumber;
+extern bool g_haveErrors;
+
 #endif /* ifndef ZILASM_PARSER */
index a086b8794c31bf29d137c3821f157def2e8a9a68..ed2b6d7c1db0e00b892e3a81a70c721830507524 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * string_table.cpp -- part of ZilUtils/ZilAsm
  *
- * Copyright (C) 2019 Jason Self <j@jxself.org>
+ * Copyright (C) 2019, 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
@@ -90,7 +90,14 @@ String_table::encrypt_string (const char *str, ZMemblock * zmb)
        }
       else if (c == ' ')
        {
-         write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, 0);
+                 //if (numberOfSymbolsInWord != 0)
+                 //{
+                        // zmem_putbyte(zmb, (w >> 8) & 255);
+                        // zmem_putbyte(zmb, w & 255);
+                        // numberOfSymbolsInWord = 0;
+                        // w = 0;
+                 //}
+                 write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, 0);
        }
       else
        {
@@ -130,7 +137,14 @@ String_table::encrypt_string (const char *str, ZMemblock * zmb)
       numberOfSymbolsInWord = 0;
       w = 0;
     }
-  zmb->contents[zmb->used_size - 2] |= 0x80;
+  
+  if ((zmb->contents[zmb->used_size - 1] & 31) == 0) // if the last symbol is a space or not filled
+         zmb->contents[zmb->used_size - 2] |= 0x80;     // then we mark this word as the last word
+  else
+  {
+         zmem_putbyte(zmb, 0x80);                       // otherwise we add one more empty word
+         zmem_putbyte(zmb, 0x0);                        // with 15-th bit set
+  }
 
   return zmb;
 }