Added ability to define multiple functions (without parameters) and master
authorJason Self <j@jxself.org>
Sun, 23 Aug 2020 15:43:45 +0000 (08:43 -0700)
committerJason Self <j@jxself.org>
Sun, 23 Aug 2020 15:43:45 +0000 (08:43 -0700)
call them

14 files changed:
zilasm/Makefile.am
zilasm/compiler.cpp [new file with mode: 0644]
zilasm/compiler.h [new file with mode: 0644]
zilasm/directives.cpp
zilasm/directives.h
zilasm/header.cpp
zilasm/header.h
zilasm/include_all.h [new file with mode: 0644]
zilasm/main.cpp
zilasm/opcodes.c
zilasm/opcodes.h
zilasm/parser.cpp
zilasm/parser.h
zilasm/string_table.cpp

index 06a834be80c0e9d4128579fc9586605b7b3e1570..78f5d37f19979a361b55ececf37de1cd8a2c33fa 100644 (file)
@@ -21,5 +21,5 @@
 
 bin_PROGRAMS = zilasm
 man_MANS = zilasm.1
 
 bin_PROGRAMS = zilasm
 man_MANS = zilasm.1
-zilasm_SOURCES = main.cpp opcodes.c symtable.c header.cpp parser.cpp directives.cpp labels.cpp string_table.cpp zmem.c
+zilasm_SOURCES = main.cpp compiler.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
 include_HEADERS =       opcodes.h symtable.h header.h parser.h directives.h labels.h string_table.h zmem.h
diff --git a/zilasm/compiler.cpp b/zilasm/compiler.cpp
new file mode 100644 (file)
index 0000000..eaa2317
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+* parser.c -- part of ZilUtils/ZilAsm
+*
+* Copyright (C) 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 "include_all.h"
+
+CCompiler::CCompiler() :m_output_file(NULL)
+{
+}
+
+int
+CCompiler::assembly()
+{
+       FILE *file = fopen(m_output_file, "wb");
+       if (file)
+       {
+               program_header_reset(6);
+               int size = sizeof(program_header);
+
+               program_header.mode = 0;
+               program_header.release = 1;     // game version
+
+               m_code_size = 0;
+               ZMemblock *zmem_code = zmem_init(65536);
+
+               unsigned current_address = 64;
+
+               if (parser.m_functions.size() > 0)
+               {
+                       //unsigned function_table_size = parser.m_functions.size() * 2;
+                       program_header.H_FUNCTIONS_OFFSET = current_address >> 3;
+                       //current_address += function_table_size;
+               }
+               else
+                       program_header.H_FUNCTIONS_OFFSET = 0;
+
+               int code_start_offset = current_address;
+
+               if (parser.m_start_function_name == "")
+                       program_header.startPC = code_start_offset >> 2;
+               else
+                       program_header.startPC = parser.m_functions.find(parser.m_start_function_name)->second.address >> 2;
+
+               // write instructions' codes
+               m_code_size = parser.output_codes(zmem_code);
+
+               if (m_code_size & 7)
+               {
+                       const int additional_mem = 8 - (m_code_size & 7);
+                       for (int i = 0; i < additional_mem; ++i)
+                               zmem_putbyte(zmem_code, 0);
+                       m_code_size += additional_mem;
+               }
+
+               program_header.dynamic_size = 8;
+
+               //Program_header.h_file_size = 33;  //sizeof(Program_header) + zmb->used_size;
+
+               //m_code_size = 8;
+
+               Word stringTableOffset = m_code_size;
+               program_header.H_STRINGS_OFFSET = (64 + stringTableOffset) >> 3;
+
+               int stringTableSize = 64;
+               program_header.h_file_size =
+                       (code_start_offset + m_code_size + stringTableSize) >> 3;
+               ZMemblock *zmb = zmem_init(program_header.h_file_size * 8);
+
+               for (int i = 0; i < m_code_size; ++i)
+                       zmem_putbyte(zmb, zmem_code->contents[i]);
+
+               zmem_destroy(zmem_code);
+
+               //zmem_putbyte(zmb, 0); // number of local variables
+               //zmem_putbyte(zmb, 141); // print addr command
+
+               //Word offset = 0;
+               //zmem_putbyte(zmb, (offset >> 8) & 255);
+               //zmem_putbyte(zmb, offset & 255);
+
+               //zmem_putbyte(zmb, 186); // quit command
+
+               // output zeros until string table begins
+               while (zmb->used_size < stringTableOffset)
+                       zmem_putbyte(zmb, 0);
+               //
+               //// fill string table with one string
+               //add_string_to_string_table("Hello, World!", zmb);
+
+               outputToFile(&program_header, file);
+               //output_function_table(file);
+
+               fwrite(zmb->contents, zmb->allocated_size, 1, file);
+               fclose(file);
+       }
+
+       return OK;
+}
+
+
+char *
+CCompiler::get_output_file_name()
+{
+       return m_output_file;
+}
+
+
+void 
+CCompiler::output_function_table(FILE *file)
+{
+       if (parser.m_functions.size())
+       {
+               for(map<string, Function>::iterator iter = parser.m_functions.begin(); iter != parser.m_functions.end(); ++iter)
+               {
+                       Word w = (iter->second.address) >> 4;
+                       fprintf ( file, "%c", (w >> 8) & 255);
+                       fprintf(file, "%c", w & 255);
+               }
+
+       }
+}
\ No newline at end of file
diff --git a/zilasm/compiler.h b/zilasm/compiler.h
new file mode 100644 (file)
index 0000000..a885819
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * compiler.h -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 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
+ */
+#ifndef ZILASM_COMPILER
+#define ZILASM_COMPILER
+
+
+typedef struct
+{
+       int todo;
+} Opcode_dict;
+
+
+
+struct String_Table_Elem
+{
+       string value;                   // value in ASCII format
+       int index;
+};
+
+
+class CCompiler
+{
+public:
+       CCompiler();
+       int assembly();
+       void fill_config(void);
+       void get_arguments(int argc, char *argv[], char *envp[]);
+       char *get_output_file_name();
+       CParser parser;
+
+private:
+       char *m_output_file;
+       list < String_Table_Elem > m_string_table;
+       int m_code_size;
+
+       char *build_output_filename(const char basename[], const char *suffix);
+       void fill_zserial(void);
+       void new_file_suffix(char *result, size_t maxlen, const char *src,
+               const char *newsuffix);
+       void output_code_section();
+       void output_function_table(FILE *file);
+       void parse_intarg(int *dest, const char name[], int min, int max,
+               int defval);
+       void parse_zserial(void);
+       void print_usage(int failed);
+       void print_version();
+       void wrong_arg(const char *err, ...);
+};
+
+enum
+{
+       FAIL = -1, OK = 0, NEED_RESTART = 1
+};
+
+#endif
index d15ba894ca7b90237735282d1b02676f7e3fbdbd..94c39f982313c9c1c9707e7a36a05992394c0ab6 100644 (file)
  * SPDX-License-Identifier: AGPL-3.0-or-later
  */
 
  * 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"
+#include "include_all.h"
 
 #define ARRAY_SIZE(x)  ((sizeof(x)) / (sizeof(x[0])))
 
 
 #define ARRAY_SIZE(x)  ((sizeof(x)) / (sizeof(x[0])))
 
@@ -38,63 +29,65 @@ stack<FILE*> g_fileHandlers;
 
 
 static int
 
 
 static int
-byte_handler (const char *args)
+byte_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-end_handler (const char *args)
+end_handler (const char *args, CParser* parser)
 {
        g_stopParsing = 1;
        return 0;
 }
 
 static int
 {
        g_stopParsing = 1;
        return 0;
 }
 
 static int
-endi_handler (const char *args)
+endi_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-endt_handler (const char *args)
+endt_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-fstr_handler (const char *args)
+fstr_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-funct_handler (const char *args)
+funct_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
 {
   /* !!! TODO !!! */
-  return 0;
+  
+       parser->add_function(args);
+       return 0;
 }
 
 static int
 }
 
 static int
-gstr_handler (const char *args)
+gstr_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-gvar_handler (const char *args)
+gvar_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-insert_handler (const char *args)
+insert_handler (const char *args, CParser* parser)
 {
        string file_name;
        char *p = (char*)args;
 {
        string file_name;
        char *p = (char*)args;
@@ -146,113 +139,90 @@ insert_handler (const char *args)
        //pc.current_file_name = s;
        g_parsing_contexts.push(pc);
        
        //pc.current_file_name = s;
        g_parsing_contexts.push(pc);
        
-       
-       unsigned saveLineNumber = g_currentLineNumber;
-       parse_file(); //s.c_str());
-       g_currentLineNumber = saveLineNumber;
+       unsigned saveLineNumber = parser->m_current_line_number;
+       parser->parse_file(); //s.c_str());
+       parser->m_current_line_number = saveLineNumber;
        return strlen(args);
 }
 
 static int
        return strlen(args);
 }
 
 static int
-len_handler (const char *args)
+len_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-newdirective_handler (const char *args)
+newdirective_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-object_handler (const char *args)
+object_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-prop_handler (const char *args)
+prop_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-str_handler (const char *args)
+str_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-strl_handler (const char *args)
+strl_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-table_handler (const char *args)
+table_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-vocbeg_handler (const char *args)
+vocbeg_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-vocend_handler (const char *args)
+vocend_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-word_handler (const char *args)
+word_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 static int
-zword_handler (const char *args)
+zword_handler (const char *args, CParser* parser)
 {
   /* !!! TODO !!! */
   return 0;
 }
 
 {
   /* !!! 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
 {
 
 typedef struct
 {
@@ -274,11 +244,40 @@ namecmp (const void *key, const void *elem)
 }
 
 Directive_handler
 }
 
 Directive_handler
-directive_lookup (const char *name, unsigned namelen)
+CDirectives::directive_lookup (const char *name, unsigned namelen)
 {
 {
-  Name n = { name, namelen };
+       // 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
+       };
+       
+       Name n = { name, namelen };
   Directive *p =
     (Directive *) bsearch (&n, Directives, ARRAY_SIZE (Directives),
                           sizeof (Directive), namecmp);
   return p ? p->handler : NULL;
 }
   Directive *p =
     (Directive *) bsearch (&n, Directives, ARRAY_SIZE (Directives),
                           sizeof (Directive), namecmp);
   return p ? p->handler : NULL;
 }
+
+
+CDirectives::CDirectives(CParser *parser) :m_parser(parser)
+{
+}
\ No newline at end of file
index b1ddd2385b444652b746ac2fec547a712155fa44..9f66060c1e16e4d550697dd7c1ad105a1e7f1940 100644 (file)
@@ -22,7 +22,9 @@
 #ifndef ZILASM_DIRECTIVES
 #define ZILASM_DIRECTIVES 1
 
 #ifndef ZILASM_DIRECTIVES
 #define ZILASM_DIRECTIVES 1
 
-typedef int (*Directive_handler) (const char *directive_args);
+class CParser;
+
+typedef int (*Directive_handler) (const char *directive_args, CParser* parser);
 
 typedef struct
 {
 
 typedef struct
 {
@@ -30,8 +32,20 @@ typedef struct
   Directive_handler handler;
 } Directive;
 
   Directive_handler handler;
 } Directive;
 
-Directive_handler directive_lookup (const char *name, unsigned namelen);
 extern int g_stopParsing;
 extern stack<FILE*> g_fileHandlers;
 
 extern int g_stopParsing;
 extern stack<FILE*> g_fileHandlers;
 
+
+class CDirectives
+{
+public:
+       CDirectives(CParser *parser);
+       Directive_handler directive_lookup(const char *name, unsigned namelen);
+
+private:
+       CParser *m_parser;
+       
+       CDirectives();
+       //int   insert_handler(const char *args);
+};
 #endif /* ifndef ZILASM_DIRECTIVES */
 #endif /* ifndef ZILASM_DIRECTIVES */
index 863c65e2b3e25d4b4e84074212068f42846087a7..c643eeb87d2ebd347a2af75dbc0b1be315d4a5c8 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * header.c -- part of ZilUtils/ZilAsm
  *
 /*
  * header.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
  *
  * 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 "header.h"
 
 
 #include "header.h"
 
-Program_header_struct Program_header;
+Program_header_struct program_header;
 
 const unsigned MAX_HEADER_LEN = 40;
 
 void
 program_header_reset (unsigned zversion)
 {
 
 const unsigned MAX_HEADER_LEN = 40;
 
 void
 program_header_reset (unsigned zversion)
 {
-  bzero (&Program_header, sizeof (Program_header));
-  Program_header.version = zversion;
+  bzero (&program_header, sizeof (program_header));
+  program_header.version = zversion;
 }
 
 ZMemblock *
 program_header_build (void)
 {
   ZMemblock *zmb = zmem_init (MAX_HEADER_LEN);
 }
 
 ZMemblock *
 program_header_build (void)
 {
   ZMemblock *zmb = zmem_init (MAX_HEADER_LEN);
-  zmem_putbyte (zmb, Program_header.version);
+  zmem_putbyte (zmb, program_header.version);
   /* TODO */
   return zmb;
 }
   /* TODO */
   return zmb;
 }
@@ -61,7 +61,9 @@ outputToFile (Program_header_struct * pHeader, FILE * file)
 
   h.startPC = swapBytes (h.startPC);
   h.h_file_size = swapBytes (h.h_file_size);
 
   h.startPC = swapBytes (h.startPC);
   h.h_file_size = swapBytes (h.h_file_size);
-  h.H_STRINGS_OFFSET = swapBytes (h.H_STRINGS_OFFSET);
+  h.H_STRINGS_OFFSET = swapBytes(h.H_STRINGS_OFFSET);
+
+  h.H_FUNCTIONS_OFFSET = swapBytes(h.H_FUNCTIONS_OFFSET);
 
   int size = sizeof (Program_header_struct);
   fwrite (&h, sizeof (Program_header_struct), 1, file);
 
   int size = sizeof (Program_header_struct);
   fwrite (&h, sizeof (Program_header_struct), 1, file);
index c63e6658855ce35572a24e08e14977962a4b80ed..5607b3a0b95ff0c43090737472a45a63cf1fb107 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * header.h -- part of ZilUtils/ZilAsm
  *
 /*
  * header.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
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -140,7 +140,7 @@ typedef struct
 } Program_header_struct;
 
 
 } Program_header_struct;
 
 
-extern Program_header_struct Program_header;
+extern Program_header_struct program_header;
 
 void program_header_reset (unsigned zversion);
 ZMemblock *program_header_build (void);
 
 void program_header_reset (unsigned zversion);
 ZMemblock *program_header_build (void);
@@ -157,5 +157,5 @@ typedef struct
 
 void outputToFile (Program_header_struct * h, FILE * file);
 
 
 void outputToFile (Program_header_struct * h, FILE * file);
 
-void relase_parser ();
+//void relase_parser ();
 #endif /* ifndef ZILASM_HEADER */
 #endif /* ifndef ZILASM_HEADER */
diff --git a/zilasm/include_all.h b/zilasm/include_all.h
new file mode 100644 (file)
index 0000000..66e0c06
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * include_all.h -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 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
+ */
+
+#pragma once
+
+#ifndef INCLUDE_ALL
+#define INCLUDE_ALL
+
+
+//#include <stdio.h>
+//#include <stdlib.h>
+//#include <stdarg.h>
+//#include <string.h>
+
+
+#include <stdlib.h>
+#include <stdio.h>             /* fopen, fgets */
+#include <stdarg.h>
+#include <string.h>            /* strlen */
+extern "C"
+{
+#include <strings.h>
+}
+#include <getopt.h>
+#include <time.h>
+#include <ctype.h>
+
+
+#include <string>
+#include <stack>
+#include <list>
+#include <vector>
+#include <map>
+using namespace std;
+
+
+
+#include "config.h"
+#include "header.h"
+extern "C"
+{
+#include "opcodes.h"
+}
+
+#include "header.h"
+#include "directives.h"
+#include "parser.h"
+
+
+//extern "C"
+//{
+//#include "opcodes.h"
+//}
+#include "labels.h"
+#include "string_table.h"
+#include "compiler.h"
+#endif
+
index 68846b03da7fb491cf82c6861d67baf59a8bdc8b..e7bd734b755f1906d51f1f1c05b49c13417903db 100644 (file)
  *
  * SPDX-License-Identifier: AGPL-3.0-or-later
  */
  *
  * SPDX-License-Identifier: AGPL-3.0-or-later
  */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <string>
-#include <list>
-#include <stack>
-using namespace std;
-
-
-extern "C"
-{
-#include <strings.h>
-}
-#include <getopt.h>
-#include <time.h>
-#include <ctype.h>
-#include "config.h"
-#include "header.h"
-extern "C"
-{
-#include "opcodes.h"
-}
-#include "parser.h"
-
-
+//
+//#include <stdio.h>
+//#include <stdlib.h>
+//#include <stdarg.h>
+//#include <string.h>
+//#include <string>
+//#include <list>
+//#include <stack>
+//#include <list>
+//#include <vector>
+//using namespace std;
+//
+//
+//extern "C"
+//{
+//#include <strings.h>
+//}
+//#include <getopt.h>
+//#include <time.h>
+//#include <ctype.h>
+//#include "config.h"
+//#include "header.h"
+//extern "C"
+//{
+//#include "opcodes.h"
+//}
+//#include "directives.h"
+//#include "parser.h"
+//#include "compiler.h"
+
+
+#include "include_all.h"
 
 const int DEFAULT_ZVERSION = 6;
 
 enum
 { ZVERSION = 11, ZORKID, ZSERIAL };
 
 
 const int DEFAULT_ZVERSION = 6;
 
 enum
 { ZVERSION = 11, ZORKID, ZSERIAL };
 
-enum
-{ FAIL = -1, OK = 0, NEED_RESTART = 1 };
+
 
 static struct option const long_options[] = {
   {"help", no_argument, NULL, 'h'},
 
 static struct option const long_options[] = {
   {"help", no_argument, NULL, 'h'},
@@ -66,152 +70,24 @@ static struct option const long_options[] = {
 };
 
 
 };
 
 
-typedef struct
-{
-  int todo;
-} Opcode_dict;
 
 
 
 
-struct
-{
-  int zversion;                        /* 0 - 8     */
-  int zorkid;                  /* 0 - 65535 */
-  char zserial[7];             /* YYMMDD    */
-  Opcode_dict *opcode_dict;
-} Config;
 
 
 
 
-struct String_Table_Elem
-{
-  string value;                        // value in ASCII format
-  int index;
-};
 
 
 
 
-class CMain
-{
-public:
-  CMain ();
-  int assembly ();
-  void fill_config (void);
-  void get_arguments (int argc, char *argv[], char *envp[]);
-
-  char *get_output_file_name ();
-private:
-  char *m_output_file;
-    list < String_Table_Elem > m_string_table;
-  int m_code_size;
-
-
-  char *build_output_filename (const char basename[], const char *suffix);
-  void fill_zserial (void);
-  void new_file_suffix (char *result, size_t maxlen, const char *src,
-                       const char *newsuffix);
-
-  void output_code_section ();
-
-  void parse_intarg (int *dest, const char name[], int min, int max,
-                    int defval);
-  void parse_zserial (void);
-  void print_usage (int failed);
-  void print_version ();
-  void wrong_arg (const char *err, ...);
-
-};
-
-
-CMain::CMain ():m_output_file (NULL)
-{
-}
-
-int
-CMain::assembly ()
-{
-  FILE *file = fopen (m_output_file, "wb");
-  if (file)
-    {
-      program_header_reset (6);
-      int size = sizeof (Program_header);
 
 
-      Program_header.mode = 0;
-      Program_header.release = 1;      // game version
 
 
-      int code_start_offset = 64;
-      Program_header.startPC = code_start_offset >> 2;
-
-      m_code_size = 0;
-      ZMemblock *zmem_code = zmem_init (65536);
-
-      /// write zero number of local variables
-      zmem_putbyte (zmem_code, 0);     // number of local variables
-      ++m_code_size;
-
-      // write instructions' codes
-      for (int i = 0; i < g_number_of_instructions; ++i)
-       {
-         for (int j = 0; j < g_codes[i]->used_size; ++j)
-           {
-             zmem_putbyte (zmem_code, g_codes[i]->contents[j]);
-             ++m_code_size;
-           }
-       }
-
-      if (m_code_size & 7)
-       m_code_size += 8 - (m_code_size & 7);
-
-      Program_header.dynamic_size = 8;
-
-      //Program_header.h_file_size = 33;  //sizeof(Program_header) + zmb->used_size;
-
-      //m_code_size = 8;
-
-      Word stringTableOffset = m_code_size;
-      Program_header.H_STRINGS_OFFSET = (64 + stringTableOffset) >> 3;
-
-      int stringTableSize = 64;
-      Program_header.h_file_size =
-       (code_start_offset + m_code_size + stringTableSize) >> 3;
-      ZMemblock *zmb = zmem_init (Program_header.h_file_size * 8);
-
-      for (int i = 0; i < m_code_size; ++i)
-       zmem_putbyte (zmb, zmem_code->contents[i]);
-
-      zmem_destroy (zmem_code);
-
-      //zmem_putbyte(zmb, 0); // number of local variables
-      //zmem_putbyte(zmb, 141); // print addr command
-
-      //Word offset = 0;
-      //zmem_putbyte(zmb, (offset >> 8) & 255);
-      //zmem_putbyte(zmb, offset & 255);
-
-      //zmem_putbyte(zmb, 186); // quit command
-
-      // output zeros until string table begins
-      while (zmb->used_size < stringTableOffset)
-       zmem_putbyte (zmb, 0);
-      //
-      //// fill string table with one string
-      //add_string_to_string_table("Hello, World!", zmb);
-
-      outputToFile (&Program_header, file);
-      fwrite (zmb->contents, zmb->allocated_size, 1, file);
-      fclose (file);
-    }
-
-  return OK;
-}
-
-
-char *
-CMain::get_output_file_name ()
+struct
 {
 {
-  return m_output_file;
-}
-
+       int zversion;                   /* 0 - 8     */
+       int zorkid;                     /* 0 - 65535 */
+       char zserial[7];                /* YYMMDD    */
+       Opcode_dict *opcode_dict;
+} Config;
 
 void
 
 void
-CMain::get_arguments (int argc, char *argv[], char *envp[])
+CCompiler::get_arguments (int argc, char *argv[], char *envp[])
 {
   int opt = 0;
   while ((opt = getopt_long (argc, argv, "hVo:", long_options, NULL)) != -1)
 {
   int opt = 0;
   while ((opt = getopt_long (argc, argv, "hVo:", long_options, NULL)) != -1)
@@ -265,7 +141,7 @@ CMain::get_arguments (int argc, char *argv[], char *envp[])
 
 
 void
 
 
 void
-CMain::wrong_arg (const char *err, ...)
+CCompiler::wrong_arg (const char *err, ...)
 {
   if (err)
     {
 {
   if (err)
     {
@@ -280,7 +156,7 @@ CMain::wrong_arg (const char *err, ...)
 
 
 void
 
 
 void
-CMain::print_version ()
+CCompiler::print_version ()
 {
   printf (PACKAGE_STRING "\n"
          "License AGPLv3+: GNU AGPL version 3 or later\n"
 {
   printf (PACKAGE_STRING "\n"
          "License AGPLv3+: GNU AGPL version 3 or later\n"
@@ -292,7 +168,7 @@ CMain::print_version ()
 
 
 void
 
 
 void
-CMain::print_usage (int failed)
+CCompiler::print_usage (int failed)
 {
   printf ("Usage: " PACKAGE_NAME " [OPTION...] [FILES...]\n"
          "\n"
 {
   printf ("Usage: " PACKAGE_NAME " [OPTION...] [FILES...]\n"
          "\n"
@@ -308,7 +184,7 @@ CMain::print_usage (int failed)
 }
 
 void
 }
 
 void
-CMain::fill_zserial (void)
+CCompiler::fill_zserial (void)
 {
   time_t t;
   struct tm *timeinfo;
 {
   time_t t;
   struct tm *timeinfo;
@@ -319,7 +195,7 @@ CMain::fill_zserial (void)
 
 
 void
 
 
 void
-CMain::fill_config (void)
+CCompiler::fill_config (void)
 {
   bzero (&Config, sizeof (Config));
   Config.zversion = DEFAULT_ZVERSION;
 {
   bzero (&Config, sizeof (Config));
   Config.zversion = DEFAULT_ZVERSION;
@@ -328,7 +204,7 @@ CMain::fill_config (void)
 
 
 void
 
 
 void
-CMain::parse_intarg (int *dest, const char name[], int min, int max,
+CCompiler::parse_intarg (int *dest, const char name[], int min, int max,
                     int defval)
 {
   if (!optarg)
                     int defval)
 {
   if (!optarg)
@@ -348,7 +224,7 @@ CMain::parse_intarg (int *dest, const char name[], int min, int max,
 
 
 void
 
 
 void
-CMain::parse_zserial (void)
+CCompiler::parse_zserial (void)
 {
   if (!optarg)
     {
 {
   if (!optarg)
     {
@@ -372,7 +248,7 @@ CMain::parse_zserial (void)
 
 
 void
 
 
 void
-CMain::new_file_suffix (char *result, size_t maxlen, const char *src,
+CCompiler::new_file_suffix (char *result, size_t maxlen, const char *src,
                        const char *newsuffix)
 {
   strncpy (result, src, maxlen);
                        const char *newsuffix)
 {
   strncpy (result, src, maxlen);
@@ -392,7 +268,7 @@ CMain::new_file_suffix (char *result, size_t maxlen, const char *src,
 
 
 char *
 
 
 char *
-CMain::build_output_filename (const char basename[], const char *suffix)
+CCompiler::build_output_filename (const char basename[], const char *suffix)
 {
   int n = strlen (basename) + strlen (suffix);
   char *ofile = (char *) malloc (n + 1);       /* todo!!! check for NULL. free. */
 {
   int n = strlen (basename) + strlen (suffix);
   char *ofile = (char *) malloc (n + 1);       /* todo!!! check for NULL. free. */
@@ -410,24 +286,22 @@ init_assembly (void)
 
 
 void
 
 
 void
-CMain::output_code_section ()
+CCompiler::output_code_section ()
 {
 
 }
 
 
 {
 
 }
 
 
-
 int
 main (int argc, char *argv[], char *envp[])
 {
 int
 main (int argc, char *argv[], char *envp[])
 {
-  CMain main;
+  CCompiler compiler;
 
 
-  main.fill_config ();
-  main.get_arguments (argc, argv, envp);
+  compiler.fill_config ();
+  compiler.get_arguments (argc, argv, envp);
   init_opcodes (Config.zversion, 0);
 
   init_opcodes (Config.zversion, 0);
 
-  init_parser ();
-
+  
        //for (int i = optind; i < argc; i++)
        //      parse_file(argv[i]);
   
        //for (int i = optind; i < argc; i++)
        //      parse_file(argv[i]);
   
@@ -452,12 +326,12 @@ main (int argc, char *argv[], char *envp[])
   }
   g_parsing_contexts.push(pc);
 
   }
   g_parsing_contexts.push(pc);
 
-  parse_file();// argv[optind]);
-  if ( !g_haveErrors )
-       main.assembly ();
+  compiler.parser.parse_file();// argv[optind]);
+  if ( !compiler.parser.have_errors())
+       compiler.assembly ();
 
   /* TODO! List global symbols */
   /* TODO! Find abbreviations */
 
   /* TODO! List global symbols */
   /* TODO! Find abbreviations */
-  relase_parser ();
+  //relase_parser ();
   return 0;
 }
   return 0;
 }
index f848e0e99d8d8c461e6d38e8aacb24cb1da2c0b6..b85b0dabeeea06383324e235fbcd1828b9d0d5f0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * opcodes.c -- part of ZilUtils/ZilAsm
  *
 /*
  * opcodes.c -- part of ZilUtils/ZilAsm
  *
- * Copyright (C) 2016, 2019 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019, 2020 Jason Self <j@jxself.org>
  *
  * Based on ZILF (c) 2010, 2015 Jesse McGrew
  *
  *
  * Based on ZILF (c) 2010, 2015 Jesse McGrew
  *
@@ -140,7 +140,7 @@ static Opcode_detailed_info detailed_opcodes[] = {
   {177, "RFALSE", "rfalse", 1, 6, Zop_term},   // Rfalse
   {184, "RSTACK", "ret_popped", 1, 6, Zop_term},       // Rstack
 //      { 268, "RTIME",       "RTIME",           5, 6, Zop_store   },              // Rtime
   {177, "RFALSE", "rfalse", 1, 6, Zop_term},   // Rfalse
   {184, "RSTACK", "ret_popped", 1, 6, Zop_term},       // Rstack
 //      { 268, "RTIME",       "RTIME",           5, 6, Zop_store   },              // Rtime
-  {176, "RTRUE", "rtrue", 1, 6, Zop_term},     // Rtrue
+  {Opcode_RTRUE, "RTRUE", "rtrue", 1, 6, Zop_term},    // Rtrue
   {181, "SAVE", "save", 1, 3, Zop_branch},     // Save_v1
   {181, "SAVE", "save", 4, 4, Zop_store},      // Save_v4
   {256, "SAVE", "save", 5, 6, Zop_store},      // Save_V5
   {181, "SAVE", "save", 1, 3, Zop_branch},     // Save_v1
   {181, "SAVE", "save", 4, 4, Zop_store},      // Save_v4
   {256, "SAVE", "save", 5, 6, Zop_store},      // Save_V5
index 53e350912f42ba17cd68b4292ddf62e388e1ee28..95a0f4fabdf1ff1ed5ae23632958fdf71e7a673a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * opcodes.h -- part of ZilUtils/ZilAsm
  *
 /*
  * opcodes.h -- part of ZilUtils/ZilAsm
  *
- * Copyright (C) 2016, 2019 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019, 2020 Jason Self <j@jxself.org>
  *
  * Based on ZILF (c) 2010, 2015 Jesse McGrew
  *
  *
  * Based on ZILF (c) 2010, 2015 Jesse McGrew
  *
@@ -56,11 +56,14 @@ enum Opcodes
   Opcode_ASHIFT = 259,
   Opcode_ASSIGNED = 255,
   Opcode_BAND = 9,
   Opcode_ASHIFT = 259,
   Opcode_ASSIGNED = 255,
   Opcode_BAND = 9,
+  Opcode_CRLF = 187,
+  Opcode_ICALL1 = 143,
+  Opcode_ICALL2 = 26,
   Opcode_PRINT = 141,
   Opcode_PRINTI = 178,
   Opcode_PRINTR = 179,
   Opcode_QUIT = 186,
   Opcode_PRINT = 141,
   Opcode_PRINTI = 178,
   Opcode_PRINTR = 179,
   Opcode_QUIT = 186,
-  Opcode_CRLF = 187
+  Opcode_RTRUE = 176
 };
 
 
 };
 
 
index 9b976d9e0b05bcade90c8674a2470d8d656a7199..1ea4aa72aa3385af85d0a5437a1259f9c41c98fe 100644 (file)
  *
  * SPDX-License-Identifier: AGPL-3.0-or-later
  */
  *
  * SPDX-License-Identifier: AGPL-3.0-or-later
  */
-#include <stdlib.h>
-#include <stdio.h>             /* fopen, fgets */
-#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 "opcodes.h"
-}
-#include "labels.h"
-#include "string_table.h"
+#include "include_all.h"
 
 
 #define iscomment(c)   ((c) == ';')
 
 
 #define iscomment(c)   ((c) == ';')
@@ -46,29 +29,58 @@ extern "C"
 //#define fatal_error(errmsg) printf(errmsg)
 #define PC NULL
 
 //#define fatal_error(errmsg) printf(errmsg)
 #define PC NULL
 
-unsigned g_number_of_instructions = 0;
 
 
-unsigned g_currentLineNumber = 0;
-//string g_source_directory;
-bool g_haveErrors = false;
 
 stack<Parsing_Context> g_parsing_contexts;
 
 
 
 stack<Parsing_Context> g_parsing_contexts;
 
 
-ZMemblock (*g_codes[MAX_NUMBER_OF_INSTRUCTIONS]);
+void
+CParser::add_function(const char *s)
+{
+       string name = "";
+       s = pass_spaces(s);
+       while (*s != 0 && *s != ' ' && *s != '\n')
+       {
+               name += *s;
+               s++;
+       }
+       
+       unsigned memory_for_function = 1;
+       unsigned alignment = 0;
+       if (m_current_address & 3)
+       {
+               alignment = 4 - (m_current_address & 3);
+               memory_for_function += alignment;
+       }
+       
+       g_codes[g_number_of_instructions] = zmem_init(memory_for_function);
+       for ( int i = 0; i < memory_for_function; ++i)
+               zmem_putbyte(g_codes[g_number_of_instructions], 0);  // output number of local variables
+       
+
+       m_function_addresses.push_back(m_current_address + alignment);
+       Function f;
+       f.address = m_current_address + alignment;
+       f.index = g_number_of_instructions;
+       m_functions.insert(make_pair(name, f)); /// add key pair: function name and current instruction index
+
+       m_current_address += memory_for_function;
+       ++g_number_of_instructions;
+}
+
 
 string
 
 string
-build_error_message(const char *message)
+CParser::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(),
 {
        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);
+               g_parsing_contexts.top().current_file_name.c_str(), m_current_line_number, message);
        return string(buff);
 }
 
 
 void
        return string(buff);
 }
 
 
 void
-fatal_error(const char *errmsg)
+CParser::fatal_error(const char *errmsg)
 {
        printf( "%s\n", errmsg);
        g_haveErrors = true;
 {
        printf( "%s\n", errmsg);
        g_haveErrors = true;
@@ -77,7 +89,7 @@ fatal_error(const char *errmsg)
 
 
 void
 
 
 void
-checksep (const char *p)
+CParser::checksep (const char *p)
 {
   if (!*p || iscomment (*p) || isspace (*p))
     return;
 {
   if (!*p || iscomment (*p) || isspace (*p))
     return;
@@ -86,7 +98,7 @@ checksep (const char *p)
 
 
 const char *
 
 
 const char *
-pass_spaces (const char *p)
+CParser::pass_spaces (const char *p)
 {
   while (p && isspace (*p))
     p++;
 {
   while (p && isspace (*p))
     p++;
@@ -104,23 +116,42 @@ pass_alnums (const char *p)
 }
 
 
 }
 
 
-int tryparse_instruction (const char *a);
-
 int
 int
-tryparse_directive (const char *p)
+CParser::tryparse_directive (const char *p)
 {
   if (*p != '.')
     return 0;
   const char *a = p + 1;
   const char *b = pass_alnums (a);
   checksep (b);
 {
   if (*p != '.')
     return 0;
   const char *a = p + 1;
   const char *b = pass_alnums (a);
   checksep (b);
-  Directive_handler f = directive_lookup (a, b - a);
+  Directive_handler f = m_pdirectives->directive_lookup (a, b - a);
   if (!f)
     return 0;
   if (!f)
     return 0;
-  return (b-a) + (*f) (b);
+  return (b-a) + (*f) (b, this);
 }
 
 
 }
 
 
+int
+CParser::tryparse_startup_directive(const char *p)
+{
+       const char *a = p;
+       string s = "%START::";
+       if (memcmp(p, s.c_str(), s.length()) == 0)
+       {
+               p += s.length();
+               while (isspace(*p))
+                       p++;
+               m_start_function_name = "";
+               while (isalnum(*p))
+                       m_start_function_name += *p++;
+
+       }
+
+       return p - a;
+}
+
+
+
 int
 tryparse_assignment (const char *a, const char *b, const char *c)
 {
 int
 tryparse_assignment (const char *a, const char *b, const char *c)
 {
@@ -129,7 +160,7 @@ tryparse_assignment (const char *a, const char *b, const char *c)
 
 
 int
 
 
 int
-tryparse_label (const char *a, const char *b, const char *c)
+CParser::tryparse_label (const char *a, const char *b, const char *c)
 {
   if (*(c + 1) != ':')
     {
 {
   if (*(c + 1) != ':')
     {
@@ -152,7 +183,7 @@ tryparse_label (const char *a, const char *b, const char *c)
 
 
 int
 
 
 int
-tryparse_name (const char *a)
+CParser::tryparse_name (const char *a)
 {
   const char *b = pass_alnums (a);
   const char *c = pass_spaces (b);
 {
   const char *b = pass_alnums (a);
   const char *c = pass_spaces (b);
@@ -167,14 +198,51 @@ tryparse_name (const char *a)
 }
 
 
 }
 
 
+int 
+CParser::read_instructions_parameter(char *a, string& str)
+{
+       int len = 0;
+       str = "";
+       char *p = (char *)pass_spaces(a);
+       if (*p == '\"')
+       {
+               p++;
+               while (*p != '\"')
+               {
+                       str += *p;
+                       ++p;
+               }
+               len = p - a;
+       }
+       return len;
+}
+
+
 int
 int
-tryparse_instruction (const char *a)
+CParser::read_instructions_parameter2(char *a, string& str)
+{
+       int len = 0;
+       str = "";
+       char *p = (char *)pass_spaces(a);
+       str="";
+       
+       const char *b = pass_alnums(p);
+       str = string(p).substr(0, b - p);
+
+       len = b - a;
+       return len;
+}
+
+int
+CParser::tryparse_instruction (const char *a)
 {
        bool display_error = false;
        int len = 0;
        const char *b = pass_alnums(a);
        if (b != a)
        {
 {
        bool display_error = false;
        int len = 0;
        const char *b = pass_alnums(a);
        if (b != a)
        {
+               string call_function_name = "";
+
                len = b ? b - a : strlen(a);
                ZOpcode *op = (ZOpcode *)symtable_lookup2(Opcodes, a, len);
                if (op)
                len = b ? b - a : strlen(a);
                ZOpcode *op = (ZOpcode *)symtable_lookup2(Opcodes, a, len);
                if (op)
@@ -184,48 +252,45 @@ tryparse_instruction (const char *a)
 
                        switch (op->opcode)
                        {
 
                        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 == '\"')
+                               case Opcode_CRLF:
+                               case Opcode_PRINT:
+                               case Opcode_QUIT:
+                               case Opcode_RTRUE:
+                                       break;
+
+                               case Opcode_PRINTI:
+                               case Opcode_PRINTR:
                                {
                                {
-                                       p++;
                                        string str;
                                        string str;
-                                       while (*p != '\"')
-                                       {
-                                               str += *p;
-                                               ++p;
-                                       }
-                                       len = p - a;
-                                       mem_additional =
-                                               String_table::encrypt_string(str.c_str(), NULL);
+                                       len += read_instructions_parameter((char *)a + len, str);
+                                       if ( str.length())
+                                               mem_additional = String_table::encrypt_string(str.c_str(), NULL);
+                                       break;
+                               }
+                               case Opcode_ICALL1:
+                               {
+                                       len += read_instructions_parameter2((char *)a + len, call_function_name);
+                                       m_calls.push_back(call_function_name);
+                                       mem_additional = zmem_init(2);   // reserve two bytes of memory for the address
+                                       zmem_putbyte(mem_additional, 0); // and write there some two bytes, e.g. zeros
+                                       zmem_putbyte(mem_additional, 0);
                                }
                                break;
                                }
                                break;
+                               default:
+                               {
+                                       display_error = true;
+                               }
                        }
                        }
-                       default:
-                       {
-                               display_error = true;
-                       }
-                       }
-
 
                        if (display_error == false)
                        {
 
                        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);
                                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);
-
+                               m_current_address += instruction_size;
                                if (mem_additional)
                                {
                                        for (int i = 0; i < mem_additional->used_size; ++i)
                                if (mem_additional)
                                {
                                        for (int i = 0; i < mem_additional->used_size; ++i)
@@ -234,13 +299,14 @@ tryparse_instruction (const char *a)
                                        zmem_destroy(mem_additional);
                                }
 
                                        zmem_destroy(mem_additional);
                                }
 
+                               
+
                                ++g_number_of_instructions;
                                return len;
                        }
                }
                else
                {
                                ++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());
                }
                        string message = "wrong line \"" + string(a) + string("\"");
                        fatal_error(build_error_message(message.c_str()).c_str());
                }
@@ -267,7 +333,7 @@ tryparse_instruction (const char *a)
  *  Line can be one from: Comment, Global label, Local label, Directive, Name=Value, Instruction
  */
 int
  *  Line can be one from: Comment, Global label, Local label, Directive, Name=Value, Instruction
  */
 int
-parse_line (const char *p)
+CParser::parse_line (const char *p)
 {
   for (; *p; p++)
     {
 {
   for (; *p; p++)
     {
@@ -277,6 +343,13 @@ parse_line (const char *p)
        continue;
       if (iscomment (c))
        return 0;
        continue;
       if (iscomment (c))
        return 0;
+         if (c == '%')
+         {
+                 if (n = tryparse_startup_directive(p))
+                         return n;
+         }
+
+
       if (n = tryparse_directive (p))
        return n;
       if (n = tryparse_name (p))
       if (n = tryparse_directive (p))
        return n;
       if (n = tryparse_name (p))
@@ -291,7 +364,7 @@ parse_line (const char *p)
 #define MAX_LINESIZE 1024
 
 int
 #define MAX_LINESIZE 1024
 
 int
-parse_file (/*const char *filename*/)
+CParser::parse_file ()
 {
        if (g_parsing_contexts.size() > 0)
        {
 {
        if (g_parsing_contexts.size() > 0)
        {
@@ -301,7 +374,7 @@ parse_file (/*const char *filename*/)
                if (fp)
                {
 
                if (fp)
                {
 
-                       g_currentLineNumber = 0;
+                       m_current_line_number = 0;
 
                        //const int MAX_LINESIZE = 1024;
                        char line[MAX_LINESIZE];
 
                        //const int MAX_LINESIZE = 1024;
                        char line[MAX_LINESIZE];
@@ -309,7 +382,7 @@ parse_file (/*const char *filename*/)
 
                        while (g_stopParsing == 0 && fgets(line, MAX_LINESIZE, fp))
                        {
 
                        while (g_stopParsing == 0 && fgets(line, MAX_LINESIZE, fp))
                        {
-                               ++g_currentLineNumber;
+                               ++m_current_line_number;
 
                                if (newline_missing)
                                        fatal_error(build_error_message("line too long").c_str());
 
                                if (newline_missing)
                                        fatal_error(build_error_message("line too long").c_str());
@@ -336,48 +409,125 @@ parse_file (/*const char *filename*/)
        return 0;
 }
 
        return 0;
 }
 
-/*
 
 
-line_passed() {
-    skip_spaces();
-    return (current_token == LINE_END || current_token == LINE_COMMENT);
+CParser::CParser() 
+{
+  g_number_of_instructions = 0;
+  m_current_line_number = 0;
+  m_current_address = 0;
+  g_haveErrors = false;
+  m_pdirectives = new CDirectives(this);
 }
 
 }
 
-if (line_passed()) continue;
-if (current_token == DIRECTIVE) {
-    if (!try_next_token(NAME))
-        fatal_error("directive contains incorrect chars")
-    handler = get_directive_handler(current_token);
-    if (!handler)
-        fatal error("unknown directive");
-    (*handler)(remaining_line);
-    if (line_passed()) continue;
-    fatal_error("unexpected line tail");
-} else if (current_token == NAME) {
-    skip_spaces();
-    if (current_token == ASSIGNMENT)
-}
-    
 
 
-*/
+CParser::~CParser ()
+{
+       for (int i = 0; i < g_number_of_instructions; ++i)
+       {
+               zmem_destroy(g_codes[i]);
+       }
+       g_number_of_instructions = 0;
+       delete m_pdirectives;
+}
 
 
 
 
-void
-init_parser ()
+ZMemblock **
+CParser::get_codes()
 {
 {
-  g_number_of_instructions = 0;
+       return g_codes;
 }
 
 
 }
 
 
+unsigned 
+CParser::get_number_of_instructions()
+{
+       return g_number_of_instructions;
+}
+
 
 
+bool 
+CParser::have_errors()
+{
+       return g_haveErrors;
+}
 
 
 
 
-void
-relase_parser ()
+void 
+CParser::calculate_function_addresses()
 {
 {
-  for (int i = 0; i < g_number_of_instructions; ++i)
-    {
-      zmem_destroy (g_codes[i]);
-    }
-  g_number_of_instructions = 0;
+       //unsigned address = 0;
+       ////map<string, Function>::iterator function_iter = m_functions.begin();
+       //unsigned j = 0;
+
+       //
+       //for (int i = 0; i < get_number_of_instructions(); ++i)
+       //{
+       //      //if (function_iter == m_functions.end())
+       //      //{
+       //      //      break;
+       //      //}
+
+       //      if (m_function_addresses[j] == address)
+       //      {
+       //              if (address & 3)
+       //                      address += 4 - (address & 3);
+       //              
+
+       //              for (map<string, Function>::iterator function_iter = m_functions.begin(); function_iter != m_functions.end(); ++function_iter)
+       //              {
+       //                      if (function_iter->second.index == i)
+       //                      {
+       //                              function_iter->second.address = address;
+       //                              break;
+       //                      }
+       //      
+       //              }
+       //              m_function_addresses[j] = address;
+       //              ++j;
+       //      }
+       //      address += g_codes[i]->used_size;
+       //}
 }
 }
+
+
+unsigned
+CParser::output_codes(ZMemblock *zmem_code)
+{
+       unsigned code_size = 0;
+       map<string, Function>::iterator function_iter = m_functions.begin();
+       unsigned address = 0;
+
+       unsigned calls_index = 0;
+       for (int i = 0; i < get_number_of_instructions(); ++i)
+       {
+               ////if ( parser.)
+               //if (function_iter != m_functions.end())
+               //{
+               //      if (function_iter->second.index == i)
+               //      {
+               //              /// write few bytes for alignment purposes
+               //              for (int j = 0; j < function_iter->second.address - address; ++j)
+               //                      zmem_putbyte(zmem_code, 0);
+               //      }
+               //}
+
+               // write actual addresses to calls
+               if (g_codes[i]->contents[0] == Opcode_ICALL1)
+               {
+                       //vector<unsigned>::iterator iter = find(m_function_addresses.begin(), m_function_addresses.end(), address);
+                       unsigned target_addr = m_functions.find(m_calls[calls_index])->second.address >> 2;
+                       g_codes[i]->contents[1] = (target_addr >> 8) & 255;
+                       g_codes[i]->contents[2] = target_addr & 255;
+                       ++calls_index;
+               }
+
+
+               for (int j = 0; j < g_codes[i]->used_size; ++j)
+               {
+                       zmem_putbyte(zmem_code, g_codes[i]->contents[j]);
+                       ++code_size;
+               }
+       }
+
+       return code_size;
+}
\ No newline at end of file
index 007d2ffe48e09817d85b9cd51b283a85a064b185..e867439cc72561507a49ecc6e9197270781dd4a5 100644 (file)
@@ -29,14 +29,72 @@ struct Instruction
   int size;
 };
 
   int size;
 };
 
-void init_parser ();
+#define MAX_NUMBER_OF_INSTRUCTIONS 65536
 
 
-int parse_file();// const char *filename);
+struct Function
+{
+       Function() : index(0), address(0), number_of_local_variables(0)
+       {
+       }
 
 
-extern unsigned g_number_of_instructions;
+       unsigned index;
+       unsigned address;
+       unsigned number_of_local_variables;
+};
 
 
-#define MAX_NUMBER_OF_INSTRUCTIONS 65536
-extern ZMemblock (*g_codes[MAX_NUMBER_OF_INSTRUCTIONS]);
+
+class CParser
+{
+public:
+       CParser();
+       ~CParser();
+       void calculate_function_addresses();
+       unsigned get_number_of_instructions();
+       ZMemblock **get_codes();
+       bool have_errors();
+       unsigned output_codes(ZMemblock *zmem_code);
+       int     parse_file();
+       void add_function(const char *s);
+       unsigned m_current_line_number;
+       unsigned m_current_address;
+
+
+       map <string, Function> m_functions;
+       vector<unsigned> m_function_addresses;
+       string m_start_function_name;
+
+private:
+       unsigned g_number_of_instructions;// = 0;
+
+
+       ZMemblock(*g_codes[MAX_NUMBER_OF_INSTRUCTIONS]);
+       bool g_haveErrors;
+       CDirectives *m_pdirectives;
+       vector<string> m_calls; // contains functions names' if current instruction is call/icall or empty string otherwise
+
+       string build_error_message(const char *message);
+       void checksep(const char *p);
+       void fatal_error(const char *errmsg);
+       int parse_line(const char *p);
+       const char *pass_spaces(const char *p);
+       int     read_instructions_parameter(char *a, string& str);
+       int     read_instructions_parameter2(char *a, string& str);
+       int     tryparse_directive(const char *p);
+       int     tryparse_startup_directive(const char *p);
+
+       int     tryparse_name(const char *a);
+       int tryparse_label(const char *a, const char *b, const char *c);
+       int tryparse_instruction(const char *a);
+};
+
+//void init_parser ();
+
+//int parse_file();// const char *filename);
+
+//extern unsigned g_number_of_instructions;
+
+
+//extern ZMemblock (*g_codes[MAX_NUMBER_OF_INSTRUCTIONS]);
 
 struct Parsing_Context
 {
 
 struct Parsing_Context
 {
@@ -45,7 +103,7 @@ struct Parsing_Context
 };
 
 extern stack<Parsing_Context> g_parsing_contexts;
 };
 
 extern stack<Parsing_Context> g_parsing_contexts;
-extern unsigned g_currentLineNumber;
-extern bool g_haveErrors;
+//extern unsigned g_currentLineNumber;
+//extern bool g_haveErrors;
 
 #endif /* ifndef ZILASM_PARSER */
 
 #endif /* ifndef ZILASM_PARSER */
index ed2b6d7c1db0e00b892e3a81a70c721830507524..4e2233db443b4a61640be2e7c16a7ca27a4fdfef 100644 (file)
@@ -90,13 +90,6 @@ String_table::encrypt_string (const char *str, ZMemblock * zmb)
        }
       else if (c == ' ')
        {
        }
       else if (c == ' ')
        {
-                 //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
                  write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, 0);
        }
       else