Added ability to define multiple functions (without parameters) and
[zilutils.git] / zilasm / compiler.cpp
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