# 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>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
bin_PROGRAMS = zilasm
man_MANS = zilasm.1
-zilasm_SOURCES = main.c opcodes.c symtable.c header.c parser.c directives.c labels.c zmem.c
-include_HEADERS = opcodes.h symtable.h header.h parser.h directives.h labels.h zmem.h
+zilasm_SOURCES = main.cpp opcodes.c symtable.c header.cpp parser.cpp directives.c 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
# Process this file with autoconf to produce a configure script.
#
# Copyright (C) 2015 Alexander Andrejevic <theflash AT sdf DOT lonestar DOT org>
+# Copyright (C) 2019 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
AC_PREREQ([2.65])
AC_INIT([zilasm], [0.1])
-AC_CONFIG_SRCDIR([main.c])
+AC_CONFIG_SRCDIR([main.cpp])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
# Checks for programs.
AC_PROG_CC
+AC_PROG_CXX
# Checks for libraries.
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-#include <stdlib.h> /* bsearch */
-#include <string.h> /* strcmp */
+#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)
+static int
+byte_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int end_handler(const char *args)
+static int
+end_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int endi_handler(const char *args)
+static int
+endi_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int endt_handler(const char *args)
+static int
+endt_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int fstr_handler(const char *args)
+static int
+fstr_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int funct_handler(const char *args)
+static int
+funct_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int gstr_handler(const char *args)
+static int
+gstr_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int gvar_handler(const char *args)
+static int
+gvar_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int insert_handler(const char *args)
+static int
+insert_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int len_handler(const char *args)
+static int
+len_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int new_handler(const char *args)
+static int
+new_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int object_handler(const char *args)
+static int
+object_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int prop_handler(const char *args)
+static int
+prop_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int str_handler(const char *args)
+static int
+str_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int strl_handler(const char *args)
+static int
+strl_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int table_handler(const char *args)
+static int
+table_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int vocbeg_handler(const char *args)
+static int
+vocbeg_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int vocend_handler(const char *args)
+static int
+vocend_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int word_handler(const char *args)
+static int
+word_handler (const char *args)
{
- /* !!! TODO !!! */
- return 0;
+ /* !!! TODO !!! */
+ return 0;
}
-static int zword_handler(const char *args)
+static int
+zword_handler (const char *args)
{
- /* !!! 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", 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
+ "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;
+typedef struct
+{
+ const char *contents;
+ unsigned length;
} Name;
-static int namecmp(const void *key, const void *elem)
+static int
+namecmp (const void *key, const void *elem)
{
- const Name *p = (Name *)key;
- const Directive *d = (Directive*)elem;
+ const Name *p = (Name *) key;
+ const Directive *d = (Directive *) elem;
- int len1 = p->length;
- int len2 = strlen(d->name);
+ int len1 = p->length;
+ int len2 = strlen (d->name);
- int rc = memcmp(p->contents, elem, len1 < len2 ? len1 : len2);
- return rc ? rc : (len1 - len2);
+ int rc = memcmp (p->contents, elem, len1 < len2 ? len1 : len2);
+ return rc ? rc : (len1 - len2);
}
-Directive_handler directive_lookup(const char *name, unsigned namelen)
+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;
+ Name n = { name, namelen };
+ Directive *p =
+ (Directive *) bsearch (&n, Directives, ARRAY_SIZE (Directives),
+ sizeof (Directive), namecmp);
+ return p ? p->handler : NULL;
}
#ifndef ZILASM_DIRECTIVES
#define ZILASM_DIRECTIVES 1
-typedef int (*Directive_handler)(const char *directive_args);
+typedef int (*Directive_handler) (const char *directive_args);
-typedef struct {
- const char name[16];
- Directive_handler handler;
+typedef struct
+{
+ const char name[16];
+ Directive_handler handler;
} Directive;
-Directive_handler directive_lookup(const char *name, unsigned namelen);
+Directive_handler directive_lookup (const char *name, unsigned namelen);
#endif /* ifndef ZILASM_DIRECTIVES */
+++ /dev/null
-/*
- * header.c -- part of ZilUtils/ZilAsm
- *
- * Copyright (C) 2016, 2019 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 <string.h> /* bzero */
-#include <assert.h>
-#include <stdio.h>
-
-#include "header.h"
-
-Program_header_struct Program_header;
-
-const unsigned MAX_HEADER_LEN = 40;
-
-void program_header_reset(unsigned zversion)
-{
- bzero(&Program_header, sizeof(Program_header));
- Program_header.version = zversion;
-}
-
-ZMemblock *program_header_build(void)
-{
- ZMemblock *zmb = zmem_init(MAX_HEADER_LEN);
- zmem_putbyte(zmb, Program_header.version);
- /* TODO */
- return zmb;
-}
-
-
-Word swapBytes(Word w)
-{
- return ((w & 255) << 8) + (w >> 8);
-}
-
-
-void outputToFile(Program_header_struct *pHeader, FILE* file)
-{
- Program_header_struct h;
- memcpy(&h, pHeader, sizeof(Program_header_struct));
-
- h.startPC = swapBytes(h.startPC);
- h.h_file_size = swapBytes(h.h_file_size);
- fwrite(&h, sizeof(Program_header_struct), 1, file);
-}
\ No newline at end of file
--- /dev/null
+/*
+ * header.c -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016, 2019 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 <string.h> /* bzero */
+#include <assert.h>
+#include <stdio.h>
+
+#include "header.h"
+
+Program_header_struct Program_header;
+
+const unsigned MAX_HEADER_LEN = 40;
+
+void
+program_header_reset (unsigned zversion)
+{
+ bzero (&Program_header, sizeof (Program_header));
+ Program_header.version = zversion;
+}
+
+ZMemblock *
+program_header_build (void)
+{
+ ZMemblock *zmb = zmem_init (MAX_HEADER_LEN);
+ zmem_putbyte (zmb, Program_header.version);
+ /* TODO */
+ return zmb;
+}
+
+
+Word
+swapBytes (Word w)
+{
+ return ((w & 255) << 8) + (w >> 8);
+}
+
+
+void
+outputToFile (Program_header_struct * pHeader, FILE * file)
+{
+ Program_header_struct h;
+ memcpy (&h, pHeader, sizeof (Program_header_struct));
+
+ h.startPC = swapBytes (h.startPC);
+ h.h_file_size = swapBytes (h.h_file_size);
+ h.H_STRINGS_OFFSET = swapBytes (h.H_STRINGS_OFFSET);
+
+ int size = sizeof (Program_header_struct);
+ fwrite (&h, sizeof (Program_header_struct), 1, file);
+}
#ifndef ZILASM_HEADER
#define ZILASM_HEADER 1
-
+extern "C"
+{
#include "zmem.h"
-
-typedef unsigned long Byte_address;
-typedef unsigned long Word_address;
+}
+typedef unsigned long Byte_address;
+typedef unsigned long Word_address;
typedef unsigned long Packed_address;
-typedef unsigned long Offset8;
-typedef unsigned short Word;
-typedef unsigned char Byte;
-typedef int Bool;
+typedef unsigned long Offset8;
+typedef unsigned short Word;
+typedef unsigned char Byte;
+typedef int Bool;
//typedef struct {
-// unsigned version; // 1..6
-// // [$01] V1..V3: Flags1
-// Bool statusline_type; // bit1: 0=score/turns, 1=hh:mm
-// Bool split_two_discs; // bit2
-// Bool statusline_notavail; // bit4
-// Bool screensplit_avail; // bit5
-// Bool varpitchfont_default; // bit6
-// // [$01] V4: Flags1
-// Bool colors_avail; // v5: bit0
-// Bool pics_avail; // v6: bit1
-// Bool bold_avail; // v4: bit2
-// Bool italic_avail; // v4: bit3
-// Bool fixedspace_avail; // v4: bit4
-// Bool sound_avail; // v6: bit5
-// Bool timedkeyb_avail; // v4: bit7
-// // Addresses
-// Byte_address highmem_base; // [$04]
-// Byte_address start_pc; // [$06], v1
-// Packed_address start_routine; // [$06], v6
-// Byte_address dictionary; // [$08]
-// Byte_address objects; // [$0A]
-// Byte_address globals; // [$0C]
-// Byte_address static_base; // [$0E]
-// // [$10] Flags2
-// Bool transcript_on; // v1: bit0
-// Bool print_fixedfont; // v3: bit1
-// Bool request_redraw; // v6: bit2
-// Bool want_pics; // v5: bit3
-// Bool want_undo; // v5: bit4
-// Bool want_mouse; // v5: bit5
-// Bool want_colors; // v5: bit6
-// Bool want_sound; // v5: bit7
-// Bool want_menus; // v5: bit8
-// //
-// Byte_address abbrevs; // [$18], v2
-// Word file_length; // [$1A], v3
-// Word checksum; // [$1C], v3
-// Byte interpreter_number; // [$1E], v4
-// Byte interpreter_version; // [$1F], v4
-// // Screen
-// Byte screen_lines; // [$20], v4 ($FF = infinite)
-// Byte screen_chars; // [$21], v4
-// Word screen_width; // [$22], v5
-// Word screen_height; // [$24], v5
-// Byte font_width; // [$26], v5/v6
-// Byte font_height; // [$27], v5/v6
-// // Tables
-// Offset8 routines; // [$28], v6
-// Offset8 strings; // [$2A], v6
-// Byte backcolor; // [$2C], v5
-// Byte forecolor; // [$2D], v5
-// Byte_address term_chartable; // [$2E], v5
-// Word width3; // [$30], v6
-// Word revnumber; // [$32], v1
-// Byte_address alphabet; // [$34], v5
-// Byte_address header_ext; // [$36], v5
+// unsigned version; // 1..6
+// // [$01] V1..V3: Flags1
+// Bool statusline_type; // bit1: 0=score/turns, 1=hh:mm
+// Bool split_two_discs; // bit2
+// Bool statusline_notavail; // bit4
+// Bool screensplit_avail; // bit5
+// Bool varpitchfont_default; // bit6
+// // [$01] V4: Flags1
+// Bool colors_avail; // v5: bit0
+// Bool pics_avail; // v6: bit1
+// Bool bold_avail; // v4: bit2
+// Bool italic_avail; // v4: bit3
+// Bool fixedspace_avail; // v4: bit4
+// Bool sound_avail; // v6: bit5
+// Bool timedkeyb_avail; // v4: bit7
+// // Addresses
+// Byte_address highmem_base; // [$04]
+// Byte_address start_pc; // [$06], v1
+// Packed_address start_routine; // [$06], v6
+// Byte_address dictionary; // [$08]
+// Byte_address objects; // [$0A]
+// Byte_address globals; // [$0C]
+// Byte_address static_base; // [$0E]
+// // [$10] Flags2
+// Bool transcript_on; // v1: bit0
+// Bool print_fixedfont; // v3: bit1
+// Bool request_redraw; // v6: bit2
+// Bool want_pics; // v5: bit3
+// Bool want_undo; // v5: bit4
+// Bool want_mouse; // v5: bit5
+// Bool want_colors; // v5: bit6
+// Bool want_sound; // v5: bit7
+// Bool want_menus; // v5: bit8
+// //
+// Byte_address abbrevs; // [$18], v2
+// Word file_length; // [$1A], v3
+// Word checksum; // [$1C], v3
+// Byte interpreter_number; // [$1E], v4
+// Byte interpreter_version; // [$1F], v4
+// // Screen
+// Byte screen_lines; // [$20], v4 ($FF = infinite)
+// Byte screen_chars; // [$21], v4
+// Word screen_width; // [$22], v5
+// Word screen_height; // [$24], v5
+// Byte font_width; // [$26], v5/v6
+// Byte font_height; // [$27], v5/v6
+// // Tables
+// Offset8 routines; // [$28], v6
+// Offset8 strings; // [$2A], v6
+// Byte backcolor; // [$2C], v5
+// Byte forecolor; // [$2D], v5
+// Byte_address term_chartable; // [$2E], v5
+// Word width3; // [$30], v6
+// Word revnumber; // [$32], v1
+// Byte_address alphabet; // [$34], v5
+// Byte_address header_ext; // [$36], v5
//} Program_header_struct;
enum MODE_FLAGS
{
- COLOR_AVAILABLE = 0,
- DISPLAY_AVAILABLE = 1,
- BOLD_AVAILABLE = 2,
- ITALIC_AVAILABLE = 4,
- MONOSPACE_AVAILABLE = 8
+ COLOR_AVAILABLE = 0,
+ DISPLAY_AVAILABLE = 1,
+ BOLD_AVAILABLE = 2,
+ ITALIC_AVAILABLE = 4,
+ MONOSPACE_AVAILABLE = 8
};
-typedef struct {
- Byte version; // 1..6
- Byte mode;
- Word release;
- Word resident_size;
- Word startPC;
- Word dictionaryTableOffset;
- Word objectsTableOffset;
- Word globalsTableOffset;
- Word dynamic_size;
- Word flags;
- unsigned char serial[6];
- Word h_abbreviations;
- Word h_file_size;
- Word checkSum;
- unsigned char interpreterNumber;
- unsigned char interpreterVersion;
- unsigned char H_SCREEN_ROWS;
- unsigned char H_SCREEN_COLS;
- Word H_SCREEN_WIDTH;
- Word H_SCREEN_HEIGHT;
- unsigned char H_FONT_HEIGHT; /* this is the font width in V5 */
- unsigned char H_FONT_WIDTH; /* this is the font height in V5 */
- Word H_FUNCTIONS_OFFSET;
- Word H_STRINGS_OFFSET;
- unsigned char H_DEFAULT_BACKGROUND;
- unsigned char H_DEFAULT_FOREGROUND;
- Word H_TERMINATING_KEYS;
- Word H_LINE_WIDTH;
- unsigned char H_STANDARD_HIGH;
- unsigned char H_STANDARD_LOW;
- Word H_ALPHABET;
- Word H_EXTENSION_TABLE;
- char USER_NAME[8];
+typedef struct
+{
+ Byte version; // 1..6
+ Byte mode;
+ Word release;
+ Word resident_size; // also it's a start of "high" memory region
+ Word startPC;
+ Word dictionaryTableOffset;
+ Word objectsTableOffset;
+ Word globalsTableOffset;
+ Word dynamic_size; // also it's a start of "static" memory region
+ Word flags;
+ unsigned char serial[6];
+ Word h_abbreviations;
+ Word h_file_size;
+ Word checkSum;
+ unsigned char interpreterNumber;
+ unsigned char interpreterVersion;
+ unsigned char H_SCREEN_ROWS;
+ unsigned char H_SCREEN_COLS;
+ Word H_SCREEN_WIDTH;
+ Word H_SCREEN_HEIGHT;
+ unsigned char H_FONT_HEIGHT; /* this is the font width in V5 */
+ unsigned char H_FONT_WIDTH; /* this is the font height in V5 */
+ Word H_FUNCTIONS_OFFSET;
+ Word H_STRINGS_OFFSET;
+ unsigned char H_DEFAULT_BACKGROUND;
+ unsigned char H_DEFAULT_FOREGROUND;
+ Word H_TERMINATING_KEYS;
+ Word H_LINE_WIDTH;
+ unsigned char H_STANDARD_HIGH;
+ unsigned char H_STANDARD_LOW;
+ Word H_ALPHABET;
+ Word H_EXTENSION_TABLE;
+ char USER_NAME[8];
} Program_header_struct;
+
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);
-typedef struct {
- Byte numberOfSelfinseringCharacters;
- Byte *pSymbols;
- Byte numberOfBytesInEachEntry;
+typedef struct
+{
+ Byte numberOfSelfinseringCharacters;
+ Byte *pSymbols;
+ Byte numberOfBytesInEachEntry;
-} Program_dictionary_struct ;
+} Program_dictionary_struct;
-void outputToFile(Program_header_struct *h, FILE* file);
+void outputToFile (Program_header_struct * h, FILE * file);
-#endif /* ifndef ZILASM_HEADER */
+void relase_parser ();
+#endif /* ifndef ZILASM_HEADER */
+++ /dev/null
-/*
- * labels.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 <assert.h>
-
-#include "labels.h"
-
-Symtable *Global_labels;
-Symtable *Local_labels;
-
-const unsigned MAX_GLOBAL_LABELS = 1024;
-const unsigned MAX_LOCAL_LABELS = 256;
-const unsigned MAX_LABEL_LEN = 32;
-const unsigned ADDRESS_SIZE = sizeof(long long); /* TODO!!! */
-
-void init_local_labels(void)
-{
- if (Local_labels)
- symtable_destroy(Local_labels);
- Local_labels = symtable_create(MAX_LOCAL_LABELS, MAX_LABEL_LEN, ADDRESS_SIZE);
-}
-
-void init_global_labels(void)
-{
- assert(Global_labels);
- Global_labels = symtable_create(MAX_GLOBAL_LABELS, MAX_LABEL_LEN, ADDRESS_SIZE);
-}
--- /dev/null
+/*
+ * labels.c -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016, 2019 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 <assert.h>
+
+#include "labels.h"
+
+Symtable *Global_labels;
+Symtable *Local_labels;
+
+const unsigned MAX_GLOBAL_LABELS = 1024;
+const unsigned MAX_LOCAL_LABELS = 256;
+const unsigned MAX_LABEL_LEN = 32;
+const unsigned ADDRESS_SIZE = sizeof (long long); /* TODO!!! */
+
+void
+init_local_labels (void)
+{
+ if (Local_labels)
+ symtable_destroy (Local_labels);
+ Local_labels =
+ symtable_create (MAX_LOCAL_LABELS, MAX_LABEL_LEN, ADDRESS_SIZE);
+}
+
+void
+init_global_labels (void)
+{
+ assert (Global_labels);
+ Global_labels =
+ symtable_create (MAX_GLOBAL_LABELS, MAX_LABEL_LEN, ADDRESS_SIZE);
+}
/*
* labels.h -- part of ZilUtils/ZilAsm
*
- * Copyright (C) 2016 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019 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
#ifndef ZILASM_LABELS
#define ZILASM_LABELS 1
-
+extern "C"
+{
#include "symtable.h"
-
+}
extern Symtable *Global_labels;
-extern Symtable *Local_labels;
+extern Symtable *Local_labels;
-extern void init_local_labels(void);
-extern void init_global_labels(void);
+extern void init_local_labels (void);
+extern void init_global_labels (void);
#endif /* ifndef ZILASM_LABELS */
+++ /dev/null
-/*
- * main.c
- *
- * Copyright (C) 2015 Alexander Andrejevic <theflash AT sdf DOT lonestar DOT org>
- * Copyright (C) 2015, 2019 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 <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <getopt.h>
-#include <time.h>
-#include <ctype.h>
-
-#include "config.h"
-
-#include "header.h"
-
-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' },
- { "version", no_argument, NULL, 'V' },
- { "output", required_argument, NULL, 'o' },
- { "zversion", required_argument, NULL, ZVERSION },
- { "zorkid", required_argument, NULL, ZORKID },
- { "serial", required_argument, NULL, ZSERIAL },
- { NULL, 0, NULL, 0 }
-};
-
-typedef struct {
- int todo;
-} Opcode_dict;
-
-struct
-{
- int zversion; /* 0 - 8 */
- int zorkid; /* 0 - 65535 */
- char zserial[7]; /* YYMMDD */
- Opcode_dict *opcode_dict;
-} Config;
-
-void wrong_arg(const char *err, ...)
-{
- if (err) {
- va_list ap;
- va_start(ap, err);
- vfprintf(stderr, err, ap);
- va_end(ap);
- }
- fprintf(stderr, "Try `" PACKAGE_NAME " --help' for more information.\n");
- exit(1);
-}
-
-void print_version()
-{
- printf( PACKAGE_STRING "\n"
- "License AGPLv3+: GNU AGPL version 3 or later\n"
- "<http://gnu.org/licenses/agpl.html>\n"
- "This is free software: you are free to change and redistribute it.\n"
- "There is NO WARRANTY, to the extent permitted by law.\n"
- );
- exit(0);
-}
-
-void print_usage(int failed)
-{
- printf("Usage: " PACKAGE_NAME " [OPTION...] [FILES...]\n"
- "\n"
- "--version Display program version and exit\n"
- "--help Display this help\n"
- "\n"
- "--zversion (accepts numbers 1 - 8, defaults to %d if not specified)\n"
- "--zorkid (integer between 0 and 65535, defaults to 0 if not specified)\n"
- "--serial (six characters of ASCII, defaults to current date\n"
- " in the form YYMMDD if not specified)\n",
- DEFAULT_ZVERSION
- );
- exit(failed);
-}
-
-void fill_zserial(void)
-{
- time_t t;
- struct tm *timeinfo;
- time (&t);
- timeinfo = localtime(&t);
- strftime (Config.zserial, sizeof(Config.zserial), "%y%m%d", timeinfo);
-}
-
-void fill_config(void)
-{
- bzero(&Config, sizeof(Config));
- Config.zversion = DEFAULT_ZVERSION;
- fill_zserial();
-}
-
-void parse_intarg(int *dest, const char name[], int min, int max, int defval)
-{
- if (!optarg) {
- *dest = defval;
- return;
- }
- int n = atoi(optarg);
- if (n >= min && n <= max) {
- *dest = n;
- return;
- }
- wrong_arg("Wrong %s value %s, must be integer between %d and %d\n",
- name, optarg, min, max);
-}
-
-void parse_zserial(void)
-{
- if (!optarg) {
- fill_zserial();
- return;
- }
- size_t n = strlen(optarg);
- if (n == sizeof(Config.zserial) - 1) {
- char *p = optarg;
- while (*p && isalnum(*p))
- p++;
- if (!*p) { /* ..optarg contains alphanumeric only? */
- strncpy(Config.zserial, optarg, sizeof(Config.zserial));
- return;
- }
- }
- wrong_arg("Wrong zserial value %s, must be 6 ascii characters\n", optarg);
-}
-
-void new_file_suffix(char *result, size_t maxlen, const char *src, const char *newsuffix)
-{
- strncpy(result, src, maxlen);
- char *p = strrchr(result, '.');
- if (p && strchr(p, '/'))
- p = NULL;
- if (p) {
- strncpy(p, newsuffix, maxlen - (p - result));
- } else {
- strncat(result, newsuffix, maxlen);
- }
- result[maxlen] = 0;
-}
-
-char *build_output_filename(const char basename[], const char *suffix)
-{
- int n = strlen(basename) + strlen(suffix);
- char *ofile = malloc(n + 1); /* todo!!! check for NULL. free. */
- new_file_suffix(ofile, n, basename, suffix);
- return ofile;
-}
-
-int init_assembly(void)
-{
- /* TODO */
- return OK;
-}
-
-int assembly(char *output_file)
-{
- /* TODO */
- FILE *file = fopen(output_file, "w");
- if (file)
- {
- program_header_reset(6);
-
- int size = sizeof(Program_header );
- //Program_header.
-
- Program_header.mode = 0; // DISPLAY_AVAILABLE | MONOSPACE_AVAILABLE;
- Program_header.release = 1; // game version
-
- Program_header.startPC = 64;
-
- Program_header.dynamic_size = 128;
- Program_header.h_file_size = 9; //sizeof(Program_header) + zmb->used_size;
-
- ZMemblock *zmb = zmem_init(Program_header.h_file_size * 8);
-
- //fprintf(file, "%c", 178); // printi command
- //fprintf(file, "hello, world!");
-
- zmem_putbyte(zmb, 186); // quit command
-
-
-
- outputToFile(&Program_header, file);
-
- //fprintf(file, "%c", 186);
- fwrite(zmb->contents, zmb->allocated_size, 1, file);
- fclose(file);
- }
-
- return OK;
-}
-
-int main(int argc, char *argv[], char *envp[])
-{
- const char *output_file = NULL;
- int i;
-
- fill_config();
-
- int opt = 0;
- while ((opt = getopt_long (argc, argv, "hVo:", long_options, NULL)) != -1) {
- switch(opt) {
- case 'h' : print_usage(0);
- case 'V' : print_version();
- case 'o' : if (output_file) wrong_arg("Output file must be given once\n");
- output_file = optarg;
- break;
- case ZVERSION: parse_intarg(&Config.zversion, "zversion", 1, 8, 1); break;
- case ZORKID : parse_intarg(&Config.zorkid, "zorkid", 0, 0xFFFF, 0); break;
- case ZSERIAL : parse_zserial(); break;
- default : wrong_arg(0);
- }
- }
-
- int first_input_file = optind;
- if (first_input_file >= argc)
- wrong_arg("Missing input file\n");
- if (!output_file)
- output_file = build_output_filename(argv[first_input_file], ".dat");
-
- // TODO: Everything :)
-
- printf("Input files:\n");
- for (i = optind; i < argc; i++)
- printf("\t%s\n", argv[i]);
-
- printf("Output file: %s\n\n", output_file);
-
- printf("Config:\n"
- "- ZVersion: %d\n"
- "- ZorkID: %d\n"
- "- ZSerial: %s\n",
- Config.zversion, Config.zorkid, Config.zserial
- );
-
- init_opcodes(Config.zversion, 0);
-
- while(init_assembly() == OK && assembly(output_file) == NEED_RESTART);
-
- /* TODO! List global symbols */
- /* TODO! Find abbreviations */
-
- return 0;
-}
--- /dev/null
+/*
+ * main.c
+ *
+ * Copyright (C) 2015 Alexander Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ * Copyright (C) 2015, 2019 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 <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+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 <string>
+#include <list>
+using namespace std;
+
+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'},
+ {"version", no_argument, NULL, 'V'},
+ {"output", required_argument, NULL, 'o'},
+ {"zversion", required_argument, NULL, ZVERSION},
+ {"zorkid", required_argument, NULL, ZORKID},
+ {"serial", required_argument, NULL, ZSERIAL},
+ {NULL, 0, NULL, 0}
+};
+
+
+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_numberOfInstructions; ++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 ()
+{
+ return m_output_file;
+}
+
+
+void
+CMain::get_arguments (int argc, char *argv[], char *envp[])
+{
+ int opt = 0;
+ while ((opt = getopt_long (argc, argv, "hVo:", long_options, NULL)) != -1)
+ {
+ switch (opt)
+ {
+ case 'h':
+ print_usage (0);
+ case 'V':
+ print_version ();
+ case 'o':
+ if (m_output_file)
+ wrong_arg ("Output file must be given once\n");
+ m_output_file = optarg;
+ break;
+ case ZVERSION:
+ parse_intarg (&Config.zversion, "zversion", 1, 8, 1);
+ break;
+ case ZORKID:
+ parse_intarg (&Config.zorkid, "zorkid", 0, 0xFFFF, 0);
+ break;
+ case ZSERIAL:
+ parse_zserial ();
+ break;
+ default:
+ wrong_arg (0);
+ }
+ }
+
+ int first_input_file = optind;
+ if (first_input_file >= argc)
+ wrong_arg ("Missing input file\n");
+ if (!m_output_file)
+ m_output_file = build_output_filename (argv[first_input_file], ".dat");
+
+ // TODO: Everything :)
+
+
+ printf ("Input files:\n");
+ for (int i = optind; i < argc; i++)
+ printf ("\t%s\n", argv[i]);
+
+ printf ("Output file: %s\n\n", m_output_file);
+
+ printf ("Config:\n"
+ "- ZVersion: %d\n"
+ "- ZorkID: %d\n"
+ "- ZSerial: %s\n", Config.zversion, Config.zorkid, Config.zserial);
+
+}
+
+
+void
+CMain::wrong_arg (const char *err, ...)
+{
+ if (err)
+ {
+ va_list ap;
+ va_start (ap, err);
+ vfprintf (stderr, err, ap);
+ va_end (ap);
+ }
+ fprintf (stderr, "Try `" PACKAGE_NAME " --help' for more information.\n");
+ exit (1);
+}
+
+
+void
+CMain::print_version ()
+{
+ printf (PACKAGE_STRING "\n"
+ "License AGPLv3+: GNU AGPL version 3 or later\n"
+ "<http://gnu.org/licenses/agpl.html>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n");
+ exit (0);
+}
+
+
+void
+CMain::print_usage (int failed)
+{
+ printf ("Usage: " PACKAGE_NAME " [OPTION...] [FILES...]\n"
+ "\n"
+ "--version Display program version and exit\n"
+ "--help Display this help\n"
+ "\n"
+ "--zversion (accepts numbers 1 - 8, defaults to %d if not specified)\n"
+ "--zorkid (integer between 0 and 65535, defaults to 0 if not specified)\n"
+ "--serial (six characters of ASCII, defaults to current date\n"
+ " in the form YYMMDD if not specified)\n",
+ DEFAULT_ZVERSION);
+ exit (failed);
+}
+
+void
+CMain::fill_zserial (void)
+{
+ time_t t;
+ struct tm *timeinfo;
+ time (&t);
+ timeinfo = localtime (&t);
+ strftime (Config.zserial, sizeof (Config.zserial), "%y%m%d", timeinfo);
+}
+
+
+void
+CMain::fill_config (void)
+{
+ bzero (&Config, sizeof (Config));
+ Config.zversion = DEFAULT_ZVERSION;
+ fill_zserial ();
+}
+
+
+void
+CMain::parse_intarg (int *dest, const char name[], int min, int max,
+ int defval)
+{
+ if (!optarg)
+ {
+ *dest = defval;
+ return;
+ }
+ int n = atoi (optarg);
+ if (n >= min && n <= max)
+ {
+ *dest = n;
+ return;
+ }
+ wrong_arg ("Wrong %s value %s, must be integer between %d and %d\n",
+ name, optarg, min, max);
+}
+
+
+void
+CMain::parse_zserial (void)
+{
+ if (!optarg)
+ {
+ fill_zserial ();
+ return;
+ }
+ size_t n = strlen (optarg);
+ if (n == sizeof (Config.zserial) - 1)
+ {
+ char *p = optarg;
+ while (*p && isalnum (*p))
+ p++;
+ if (!*p)
+ { /* ..optarg contains alphanumeric only? */
+ strncpy (Config.zserial, optarg, sizeof (Config.zserial));
+ return;
+ }
+ }
+ wrong_arg ("Wrong zserial value %s, must be 6 ascii characters\n", optarg);
+}
+
+
+void
+CMain::new_file_suffix (char *result, size_t maxlen, const char *src,
+ const char *newsuffix)
+{
+ strncpy (result, src, maxlen);
+ char *p = strrchr (result, '.');
+ if (p && strchr (p, '/'))
+ p = NULL;
+ if (p)
+ {
+ strncpy (p, newsuffix, maxlen - (p - result));
+ }
+ else
+ {
+ strncat (result, newsuffix, maxlen);
+ }
+ result[maxlen] = 0;
+}
+
+
+char *
+CMain::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. */
+ new_file_suffix (ofile, n, basename, suffix);
+ return ofile;
+}
+
+
+int
+init_assembly (void)
+{
+ /* TODO */
+ return OK;
+}
+
+
+void
+CMain::output_code_section ()
+{
+
+}
+
+
+
+int
+main (int argc, char *argv[], char *envp[])
+{
+ CMain main;
+
+ main.fill_config ();
+ main.get_arguments (argc, argv, envp);
+ init_opcodes (Config.zversion, 0);
+
+ init_parser ();
+
+ for (int i = optind; i < argc; i++)
+ parse_file (argv[i]);
+ main.assembly ();
+
+ /* TODO! List global symbols */
+ /* TODO! Find abbreviations */
+ relase_parser ();
+ return 0;
+}
/*
* opcodes.c -- part of ZilUtils/ZilAsm
*
- * Copyright (C) 2016 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019 Jason Self <j@jxself.org>
*
* Based on ZILF (c) 2010, 2015 Jesse McGrew
*
#include "opcodes.h"
-typedef struct {
- unsigned opcode;
- const char *classic_name;
- const char *inform_name;
- int minver;
- int maxver;
- ZOpcode_flags flags;
+typedef struct
+{
+ unsigned opcode;
+ const char *classic_name;
+ const char *inform_name;
+ int minver;
+ int maxver;
+ ZOpcode_flags flags;
} Opcode_detailed_info;
+
static Opcode_detailed_info detailed_opcodes[] = {
- { 20, "ADD", "add", 1, 6, Zop_store }, // Add
- { 259, "ASHIFT", "art_shift", 5, 6, Zop_store }, // Ashift
- { 255, "ASSIGNED?", "check_arg_count", 5, 6, Zop_branch | Zop_indvar }, // Assigned_P
- { 9, "BAND", "and", 1, 6, Zop_store }, // Band
- { 143, "BCOM", "not", 1, 4, Zop_store }, // Bcom_V1
- { 248, "BCOM", "not", 5, 6, Zop_store }, // Bcom_V5
- { 8, "BOR", "or", 1, 6, Zop_store }, // Bor
- { 7, "BTST", "test", 1, 6, Zop_branch }, // Btst
- { 242, "BUFOUT", "buffer_mode", 4, 6, 0 }, // Bufout
- { 224, "CALL", "call_vs", 1, 6, Zop_store | Zop_call }, // Call
- { 136, "CALL1", "call_1s", 4, 6, Zop_store | Zop_call }, // Call1
- { 25, "CALL2", "call_2s", 4, 6, Zop_store | Zop_call }, // Call2
- { 185, "CATCH", "catch", 5, 6, Zop_store }, // Catch
- { 268, "CHECKU", "check_unicode", 5, 6, Zop_store }, // Checku
- { 237, "CLEAR", "erase_window", 4, 6, 0 }, // Clear
- { 27, "COLOR", "set_colour", 5, 5, 0 }, // Color_v5
- { 27, "COLOR", "set_colour", 6, 6, Zop_varargs }, // Color_v6
- { 253, "COPYT", "copy_table", 5, 6, 0 }, // Copyt
- { 187, "CRLF", "new_line", 1, 6, 0 }, // Crlf
- { 240, "CURGET", "get_cursor", 4, 6, 0 }, // Curget
- { 239, "CURSET", "set_cursor", 4, 6, 0 }, // Curset
- { 263, "DCLEAR", "erase_picture", 6, 6, 0 }, // Dclear
- { 134, "DEC", "dec", 1, 6, Zop_indvar }, // Dec
- { 244, "DIRIN", "input_stream", 3, 6, 0 }, // Dir-In
- { 243, "DIROUT", "output_stream", 3, 6, 0 }, // Dir-Out
- { 261, "DISPLAY", "draw_picture", 6, 6, 0 }, // Display
- { 23, "DIV", "div", 1, 6, Zop_store }, // Div
- { 4, "DLESS?", "dec_chk", 1, 6, Zop_branch | Zop_indvar }, // Dless_P
-// { 271, "ENDMOVE", "ENDMOVE", 5, 6, Zop_store }, // Endmove = 271
- { 1, "EQUAL?", "jeq", 1, 6, Zop_branch | Zop_varargs }, // Equal_P
- { 238, "ERASE", "erase_line", 4, 6, 0 }, // Erase
- { 12, "FCLEAR", "clear_attr", 1, 6, 0 }, // Fclear
- { 130, "FIRST?", "get_child", 1, 6, Zop_store | Zop_branch }, // First_P
- { 260, "FONT", "set_font", 5, 6, Zop_store }, // Font
- { 11, "FSET", "set_attr", 1, 6, 0 }, // Fset
- { 10, "FSET?", "test_attr", 1, 6, Zop_branch }, // Fset_P
- { 185, "FSTACK", "pop", 1, 4, 0 }, // Fstack_V1
- { 277, "FSTACK", "pop_stack", 6, 6, 0 }, // Fstack_V6
- { 15, "GET", "loadw", 1, 6, Zop_store }, // Get
- { 16, "GETB", "loadb", 1, 6, Zop_store }, // Getb
- { 17, "GETP", "get_prop", 1, 6, Zop_store }, // Getp
- { 18, "GETPT", "get_prop_addr", 1, 6, Zop_store }, // Getpt
- { 3, "GRTR?", "jg", 1, 6, Zop_branch }, // Grtr_P
- { 241, "HLIGHT", "set_text_style", 4, 6, 0 }, // Hlight
- { 249, "ICALL", "call_vn", 5, 6, Zop_call }, // Icall
- { 143, "ICALL1", "call_1n", 5, 6, Zop_call }, // Icall1
- { 26, "ICALL2", "call_2n", 5, 6, Zop_call }, // Icall2
- { 5, "IGRTR?", "inc_chk", 1, 6, Zop_branch | Zop_indvar }, // Igrtr_P
- { 6, "IN?", "jin", 1, 6, Zop_branch }, // In_P
- { 133, "INC", "inc", 1, 6, Zop_indvar }, // Inc
- { 246, "INPUT", "read_char", 4, 6, Zop_store }, // Input
- { 247, "INTBL?", "scan_table", 4, 6, Zop_store | Zop_branch }, // Intbl_P
- { 266, "IRESTORE", "restore_undo", 5, 6, Zop_store }, // Irestore
- { 265, "ISAVE", "save_undo", 5, 6, Zop_store }, // Isave
- { 250, "IXCALL", "call_vn2", 5, 6, Zop_extra | Zop_call }, // Ixcall
- { 140, "JUMP", "jump", 1, 6, Zop_label | Zop_term }, // Jump
- { 2, "LESS?", "jl", 1, 6, Zop_branch }, // Less_P
- { 251, "LEX", "tokenise", 5, 6, 0 }, // Lex
- { 131, "LOC", "get_parent", 1, 6, Zop_store }, // Loc
- { 264, "MARGIN", "set_margins", 6, 6, 0 }, // Margin
- { 283, "MENU", "make_menu", 6, 6, Zop_branch }, // Menu
- { 24, "MOD", "mod", 1, 6, Zop_store }, // Mod
- { 278, "MOUSE-INFO", "read_mouse", 6, 6, 0 }, // MouseInfo
- { 279, "MOUSE-LIMIT", "mouse_window", 6, 6, 0 }, // MouseLimit
- { 14, "MOVE", "insert_obj", 1, 6, 0 }, // Move
- { 22, "MUL", "mul", 1, 6, Zop_store }, // Mul
- { 129, "NEXT?", "get_sibling", 1, 6, Zop_store | Zop_branch }, // Next_P
- { 19, "NEXTP", "get_next_prop", 1, 6, Zop_store }, // Nextp
- { 180, "NOOP", "nop", 1, 6, 0 }, // Noop
- { 191, "ORIGINAL?", "piracy", 5, 6, Zop_branch }, // Original_P
- { 262, "PICINF", "picture_data", 6, 6, Zop_branch }, // Picinf
- { 284, "PICSET", "picture_table", 6, 6, 0 }, // Picset
- { 233, "POP", "pull", 1, 5, 0 }, // Pop_v1
- { 233, "POP", "pull", 6, 6, Zop_store }, // Pop_v6
- { 141, "PRINT", "print_paddr", 1, 6, 0 }, // Print
- { 135, "PRINTB", "print_addr", 1, 6, 0 }, // Printb
- { 229, "PRINTC", "print_char", 1, 6, 0 }, // Printc
- { 138, "PRINTD", "print_obj", 1, 6, 0 }, // Printd
- { 282, "PRINTF", "print_form", 6, 6, 0 }, // Printf
- { 178, "PRINTI", "print", 1, 6, Zop_string }, // Printi
-// { 267, "PRINTMOVE", "PRINTMOVE", 5, 6, Zop_store }, // Printmove
- { 230, "PRINTN", "print_num", 1, 6, 0 }, // Printn
- { 179, "PRINTR", "print_ret", 1, 6, Zop_string | Zop_term }, // Printr
- { 254, "PRINTT", "print_table", 5, 6, 0 }, // Printt
- { 267, "PRINTU", "print_unicode", 5, 6, 0 }, // Printu
- { 132, "PTSIZE", "get_prop_len", 1, 6, Zop_store }, // Ptsize
- { 232, "PUSH", "push", 1, 6, 0 }, // Push
- { 225, "PUT", "storew", 1, 6, 0 }, // Put
- { 226, "PUTB", "storeb", 1, 6, 0 }, // Putb
- { 227, "PUTP", "put_prop", 1, 6, 0 }, // Putp
- { 186, "QUIT", "quit", 1, 6, Zop_term }, // Quit
- { 231, "RANDOM", "random", 1, 6, Zop_store }, // Random
- { 228, "READ", "sread", 1, 4, 0 }, // Read_v1
- { 228, "READ", "aread", 5, 6, Zop_store }, // Read_v5
- { 137, "REMOVE", "remove_obj", 1, 6, 0 }, // Remove
- { 183, "RESTART", "restart", 1, 6, Zop_term }, // Restart
- { 182, "RESTORE", "restore", 1, 3, Zop_branch }, // Restore_v1
- { 182, "RESTORE", "restore", 4, 4, Zop_store }, // Restore_v4
- { 257, "RESTORE", "restore", 5, 6, Zop_store }, // Restore_V5
- { 139, "RETURN", "ret", 1, 6, Zop_term }, // Return
- { 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
- { 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
- { 235, "SCREEN", "set_window", 3, 6, 0 }, // Screen
- { 276, "SCROLL", "scroll_window", 6, 6, 0 }, // Scroll
-// { 269, "SEND", "SEND", 5, 6, Zop_store }, // Send
- { 270, "SERVER", "SERVER", 5, 6, Zop_store }, // Server
- { 13, "SET", "store", 1, 6, Zop_indvar }, // Set
- { 258, "SHIFT", "log_shift", 5, 6, Zop_store }, // Shift
- { 245, "SOUND", "sound_effect", 3, 6, 0 }, // Sound
- { 234, "SPLIT", "split_window", 3, 6, 0 }, // Split
- { 21, "SUB", "sub", 1, 6, Zop_store }, // Sub
- { 28, "THROW", "throw", 5, 6, Zop_term }, // Throw
- { 188, "USL", "show_status", 1, 3, 0 }, // Usl
- { 142, "VALUE", "load", 1, 6, Zop_store | Zop_indvar }, // Value
- { 189, "VERIFY", "verify", 3, 6, Zop_branch }, // Verify
- { 274, "WINATTR", "window_style", 6, 6, 0 }, // Winattr
- { 275, "WINGET", "get_wind_prop", 6, 6, Zop_store }, // Winget
- { 272, "WINPOS", "move_window", 6, 6, 0 }, // Winpos
- { 281, "WINPUT", "put_wind_prop", 6, 6, 0 }, // Winput
- { 273, "WINSIZE", "window_size", 6, 6, 0 }, // Winsize
- { 236, "XCALL", "call_vs2", 4, 6, Zop_store | Zop_extra | Zop_call }, // Xcall
- { 280, "XPUSH", "push_stack", 6, 6, Zop_branch }, // Xpush
- { 128, "ZERO?", "jz", 1, 6, Zop_branch }, // Zero_P
- { 252, "ZWSTR", "encode_text", 5, 6, 0 } // Zwstr
+ {Opcode_ADD, "ADD", "add", 1, 6, Zop_store}, // Add
+ {Opcode_ASHIFT, "ASHIFT", "art_shift", 5, 6, Zop_store}, // Ashift
+ {Opcode_ASSIGNED, "ASSIGNED?", "check_arg_count", 5, 6, Zop_branch | Zop_indvar}, // Assigned_P
+ {Opcode_BAND, "BAND", "and", 1, 6, Zop_store}, // Band
+ {143, "BCOM", "not", 1, 4, Zop_store}, // Bcom_V1
+ {248, "BCOM", "not", 5, 6, Zop_store}, // Bcom_V5
+ {8, "BOR", "or", 1, 6, Zop_store}, // Bor
+ {7, "BTST", "test", 1, 6, Zop_branch}, // Btst
+ {242, "BUFOUT", "buffer_mode", 4, 6, 0}, // Bufout
+ {224, "CALL", "call_vs", 1, 6, Zop_store | Zop_call}, // Call
+ {136, "CALL1", "call_1s", 4, 6, Zop_store | Zop_call}, // Call1
+ {25, "CALL2", "call_2s", 4, 6, Zop_store | Zop_call}, // Call2
+ {185, "CATCH", "catch", 5, 6, Zop_store}, // Catch
+ {268, "CHECKU", "check_unicode", 5, 6, Zop_store}, // Checku
+ {237, "CLEAR", "erase_window", 4, 6, 0}, // Clear
+ {27, "COLOR", "set_colour", 5, 5, 0}, // Color_v5
+ {27, "COLOR", "set_colour", 6, 6, Zop_varargs}, // Color_v6
+ {253, "COPYT", "copy_table", 5, 6, 0}, // Copyt
+ {187, "CRLF", "new_line", 1, 6, 0}, // Crlf
+ {240, "CURGET", "get_cursor", 4, 6, 0}, // Curget
+ {239, "CURSET", "set_cursor", 4, 6, 0}, // Curset
+ {263, "DCLEAR", "erase_picture", 6, 6, 0}, // Dclear
+ {134, "DEC", "dec", 1, 6, Zop_indvar}, // Dec
+ {244, "DIRIN", "input_stream", 3, 6, 0}, // Dir-In
+ {243, "DIROUT", "output_stream", 3, 6, 0}, // Dir-Out
+ {261, "DISPLAY", "draw_picture", 6, 6, 0}, // Display
+ {23, "DIV", "div", 1, 6, Zop_store}, // Div
+ {4, "DLESS?", "dec_chk", 1, 6, Zop_branch | Zop_indvar}, // Dless_P
+// { 271, "ENDMOVE", "ENDMOVE", 5, 6, Zop_store }, // Endmove = 271
+ {1, "EQUAL?", "jeq", 1, 6, Zop_branch | Zop_varargs}, // Equal_P
+ {238, "ERASE", "erase_line", 4, 6, 0}, // Erase
+ {12, "FCLEAR", "clear_attr", 1, 6, 0}, // Fclear
+ {130, "FIRST?", "get_child", 1, 6, Zop_store | Zop_branch}, // First_P
+ {260, "FONT", "set_font", 5, 6, Zop_store}, // Font
+ {11, "FSET", "set_attr", 1, 6, 0}, // Fset
+ {10, "FSET?", "test_attr", 1, 6, Zop_branch}, // Fset_P
+ {185, "FSTACK", "pop", 1, 4, 0}, // Fstack_V1
+ {277, "FSTACK", "pop_stack", 6, 6, 0}, // Fstack_V6
+ {15, "GET", "loadw", 1, 6, Zop_store}, // Get
+ {16, "GETB", "loadb", 1, 6, Zop_store}, // Getb
+ {17, "GETP", "get_prop", 1, 6, Zop_store}, // Getp
+ {18, "GETPT", "get_prop_addr", 1, 6, Zop_store}, // Getpt
+ {3, "GRTR?", "jg", 1, 6, Zop_branch}, // Grtr_P
+ {241, "HLIGHT", "set_text_style", 4, 6, 0}, // Hlight
+ {249, "ICALL", "call_vn", 5, 6, Zop_call}, // Icall
+ {143, "ICALL1", "call_1n", 5, 6, Zop_call}, // Icall1
+ {26, "ICALL2", "call_2n", 5, 6, Zop_call}, // Icall2
+ {5, "IGRTR?", "inc_chk", 1, 6, Zop_branch | Zop_indvar}, // Igrtr_P
+ {6, "IN?", "jin", 1, 6, Zop_branch}, // In_P
+ {133, "INC", "inc", 1, 6, Zop_indvar}, // Inc
+ {246, "INPUT", "read_char", 4, 6, Zop_store}, // Input
+ {247, "INTBL?", "scan_table", 4, 6, Zop_store | Zop_branch}, // Intbl_P
+ {266, "IRESTORE", "restore_undo", 5, 6, Zop_store}, // Irestore
+ {265, "ISAVE", "save_undo", 5, 6, Zop_store}, // Isave
+ {250, "IXCALL", "call_vn2", 5, 6, Zop_extra | Zop_call}, // Ixcall
+ {140, "JUMP", "jump", 1, 6, Zop_label | Zop_term}, // Jump
+ {2, "LESS?", "jl", 1, 6, Zop_branch}, // Less_P
+ {251, "LEX", "tokenise", 5, 6, 0}, // Lex
+ {131, "LOC", "get_parent", 1, 6, Zop_store}, // Loc
+ {264, "MARGIN", "set_margins", 6, 6, 0}, // Margin
+ {283, "MENU", "make_menu", 6, 6, Zop_branch}, // Menu
+ {24, "MOD", "mod", 1, 6, Zop_store}, // Mod
+ {278, "MOUSE-INFO", "read_mouse", 6, 6, 0}, // MouseInfo
+ {279, "MOUSE-LIMIT", "mouse_window", 6, 6, 0}, // MouseLimit
+ {14, "MOVE", "insert_obj", 1, 6, 0}, // Move
+ {22, "MUL", "mul", 1, 6, Zop_store}, // Mul
+ {129, "NEXT?", "get_sibling", 1, 6, Zop_store | Zop_branch}, // Next_P
+ {19, "NEXTP", "get_next_prop", 1, 6, Zop_store}, // Nextp
+ {180, "NOOP", "nop", 1, 6, 0}, // Noop
+ {191, "ORIGINAL?", "piracy", 5, 6, Zop_branch}, // Original_P
+ {262, "PICINF", "picture_data", 6, 6, Zop_branch}, // Picinf
+ {284, "PICSET", "picture_table", 6, 6, 0}, // Picset
+ {233, "POP", "pull", 1, 5, 0}, // Pop_v1
+ {233, "POP", "pull", 6, 6, Zop_store}, // Pop_v6
+ {Opcode_PRINT, "PRINT", "print_paddr", 1, 6, 0}, // Print
+ {135, "PRINTB", "print_addr", 1, 6, 0}, // Printb
+ {229, "PRINTC", "print_char", 1, 6, 0}, // Printc
+ {138, "PRINTD", "print_obj", 1, 6, 0}, // Printd
+ {282, "PRINTF", "print_form", 6, 6, 0}, // Printf
+ {Opcode_PRINTI, "PRINTI", "print", 1, 6, Zop_string}, // Printi
+// { 267, "PRINTMOVE", "PRINTMOVE", 5, 6, Zop_store }, // Printmove
+ {230, "PRINTN", "print_num", 1, 6, 0}, // Printn
+ {Opcode_PRINTR, "PRINTR", "print_ret", 1, 6, Zop_string | Zop_term}, // Printr
+ {254, "PRINTT", "print_table", 5, 6, 0}, // Printt
+ {267, "PRINTU", "print_unicode", 5, 6, 0}, // Printu
+ {132, "PTSIZE", "get_prop_len", 1, 6, Zop_store}, // Ptsize
+ {232, "PUSH", "push", 1, 6, 0}, // Push
+ {225, "PUT", "storew", 1, 6, 0}, // Put
+ {226, "PUTB", "storeb", 1, 6, 0}, // Putb
+ {227, "PUTP", "put_prop", 1, 6, 0}, // Putp
+ {Opcode_QUIT, "QUIT", "quit", 1, 6, Zop_term}, // Quit
+ {231, "RANDOM", "random", 1, 6, Zop_store}, // Random
+ {228, "READ", "sread", 1, 4, 0}, // Read_v1
+ {228, "READ", "aread", 5, 6, Zop_store}, // Read_v5
+ {137, "REMOVE", "remove_obj", 1, 6, 0}, // Remove
+ {183, "RESTART", "restart", 1, 6, Zop_term}, // Restart
+ {182, "RESTORE", "restore", 1, 3, Zop_branch}, // Restore_v1
+ {182, "RESTORE", "restore", 4, 4, Zop_store}, // Restore_v4
+ {257, "RESTORE", "restore", 5, 6, Zop_store}, // Restore_V5
+ {139, "RETURN", "ret", 1, 6, Zop_term}, // Return
+ {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
+ {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
+ {235, "SCREEN", "set_window", 3, 6, Zop_none}, // Screen
+ {276, "SCROLL", "scroll_window", 6, 6, Zop_none}, // Scroll
+// { 269, "SEND", "SEND", 5, 6, Zop_store }, // Send
+ {270, "SERVER", "SERVER", 5, 6, Zop_store}, // Server
+ {13, "SET", "store", 1, 6, Zop_indvar}, // Set
+ {258, "SHIFT", "log_shift", 5, 6, Zop_store}, // Shift
+ {245, "SOUND", "sound_effect", 3, 6, 0}, // Sound
+ {234, "SPLIT", "split_window", 3, 6, 0}, // Split
+ {21, "SUB", "sub", 1, 6, Zop_store}, // Sub
+ {28, "THROW", "throw", 5, 6, Zop_term}, // Throw
+ {188, "USL", "show_status", 1, 3, 0}, // Usl
+ {142, "VALUE", "load", 1, 6, Zop_store | Zop_indvar}, // Value
+ {189, "VERIFY", "verify", 3, 6, Zop_branch}, // Verify
+ {274, "WINATTR", "window_style", 6, 6, 0}, // Winattr
+ {275, "WINGET", "get_wind_prop", 6, 6, Zop_store}, // Winget
+ {272, "WINPOS", "move_window", 6, 6, 0}, // Winpos
+ {281, "WINPUT", "put_wind_prop", 6, 6, 0}, // Winput
+ {273, "WINSIZE", "window_size", 6, 6, 0}, // Winsize
+ {236, "XCALL", "call_vs2", 4, 6, Zop_store | Zop_extra | Zop_call}, // Xcall
+ {280, "XPUSH", "push_stack", 6, 6, Zop_branch}, // Xpush
+ {128, "ZERO?", "jz", 1, 6, Zop_branch}, // Zero_P
+ {252, "ZWSTR", "encode_text", 5, 6, Zop_none} // Zwstr
};
Symtable *Opcodes;
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-void init_opcodes(int version, int inform_syntax)
+void
+init_opcodes (int version, int inform_syntax)
{
- const unsigned maxnamelen = 16;
- int n;
- if (Opcodes) symtable_destroy(Opcodes);
- Opcodes = symtable_create(2 * ARRAY_SIZE(detailed_opcodes), maxnamelen, sizeof(ZOpcode));
- assert(Opcodes);
- for(n = 0; n < ARRAY_SIZE(detailed_opcodes); n++) {
- Opcode_detailed_info *p = &detailed_opcodes[n];
- if (version < p->minver) continue;
- if (version > p->maxver) continue;
- ZOpcode q = { p->opcode, p->flags };
- symtable_add(Opcodes, inform_syntax ? p->inform_name : p->classic_name, &q);
- }
+ const unsigned maxnamelen = 16;
+ int n;
+ if (Opcodes)
+ symtable_destroy (Opcodes);
+ Opcodes =
+ symtable_create (2 * ARRAY_SIZE (detailed_opcodes), maxnamelen,
+ sizeof (ZOpcode));
+ assert (Opcodes);
+ for (n = 0; n < ARRAY_SIZE (detailed_opcodes); n++)
+ {
+ Opcode_detailed_info *p = &detailed_opcodes[n];
+ if (version < p->minver)
+ continue;
+ if (version > p->maxver)
+ continue;
+ ZOpcode q = { p->opcode, p->flags };
+ symtable_add (Opcodes, inform_syntax ? p->inform_name : p->classic_name,
+ &q);
+ }
}
/*
* opcodes.h -- part of ZilUtils/ZilAsm
*
- * Copyright (C) 2016 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019 Jason Self <j@jxself.org>
*
* Based on ZILF (c) 2010, 2015 Jesse McGrew
*
#include "symtable.h"
-typedef enum {
- Zop_none = 0,
- Zop_store = 1, // ..stores a result
- Zop_branch = 2, // ..branches to a label
- Zop_extra = 4, // ..takes an extra operand type byte, for a total of 8 possible operands
- Zop_varargs = 8, // ..is nominally 2OP but can take up to 4 operands
- Zop_string = 16, // ..has a string literal operand
- Zop_label = 32, // ..can take a local label operand
- Zop_indvar = 64, // ..first operand is an indirect variable number
- Zop_call = 128, // ..first operand is a packed routine address
- Zop_term = 256 // ..control flow does not pass to the following instruction
+typedef enum
+{
+ Zop_none = 0,
+ Zop_store = 1, // ..stores a result
+ Zop_branch = 2, // ..branches to a label
+ Zop_extra = 4, // ..takes an extra operand type byte, for a total of 8 possible operands
+ Zop_varargs = 8, // ..is nominally 2OP but can take up to 4 operands
+ Zop_string = 16, // ..has a string literal operand
+ Zop_label = 32, // ..can take a local label operand
+ Zop_indvar = 64, // ..first operand is an indirect variable number
+ Zop_call = 128, // ..first operand is a packed routine address
+ Zop_term = 256 // ..control flow does not pass to the following instruction
} ZOpcode_flags;
-typedef struct {
- unsigned opcode;
- ZOpcode_flags flags;
+typedef struct
+{
+ unsigned opcode;
+ ZOpcode_flags flags;
} ZOpcode;
extern Symtable *Opcodes;
-void init_opcodes(int version, int inform_syntax);
+void init_opcodes (int version, int inform_syntax);
-#endif /* ifndef ZILASM_OPCODES */
+enum Opcodes
+{
+ Opcode_ADD = 20,
+ Opcode_ASHIFT = 259,
+ Opcode_ASSIGNED = 255,
+ Opcode_BAND = 9,
+ Opcode_PRINT = 141,
+ Opcode_PRINTI = 178,
+ Opcode_PRINTR = 179,
+ Opcode_QUIT = 186,
+ Opcode_CRLF = 187
+};
+
+
+#endif /* ifndef ZILASM_OPCODES */
+++ /dev/null
-/*
- * parser.c -- part of ZilUtils/ZilAsm
- *
- * Copyright (C) 2016, 2019 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 <stdio.h> /* fopen, fgets */
-#include <string.h> /* strlen */
-
-#include "parser.h"
-#include "directives.h"
-#include "opcodes.h"
-#include "labels.h"
-
-#define iscomment(c) ((c) == '#')
-#define isbindigit(c) ((c) == '0' || (c) == '1')
-
-/* !!! TODO !!! */
-#define fatal_error(errmsg)
-#define PC NULL
-
-void checksep(const char *p)
-{
- if (!*p || iscomment(*p) || isspace(*p)) return;
- fatal_error("wrong chars");
-}
-
-const char *pass_spaces(const char *p)
-{
- while(p && isspace(*p)) p++;
- return (p && *p) ? p : NULL;
-}
-
-const char *pass_alnums(const char *p)
-{
- while(p && isalnum(*p)) p++;
- return (p && *p) ? p : NULL;
-}
-
-int tryparse_directive(const char *p)
-{
- 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);
- if (!f) return 0;
- return (*f)(b);
-}
-
-int tryparse_assignment(const char *a, const char *b, const char *c)
-{
- return 0;
-}
-
-int tryparse_label(const char *a, const char *b, const char *c)
-{
- if (*(c+1) != ':') {
- symtable_add2(Local_labels, a, b - a, PC);
- } else if (*(c+2) != ':') {
- symtable_add2(Global_labels, a, b - a, PC);
- } else {
- fatal_error("wrong label type");
- }
-
- while (*c++ == ':');
- if (*c && ((c = pass_spaces(c)) != NULL) && *c)
- return tryparse_instruction(c);
- return 1;
-}
-
-int tryparse_name(const char *a)
-{
- const char *b = pass_alnums(a);
- const char *c = pass_spaces(b);
-
- if (!c) return 0;
- if (*c == '=') return tryparse_assignment(a, b, c + 1);
- if (*c == ':') return tryparse_label(a, b, c);
- return 0;
-}
-
-int tryparse_instruction(const char *a)
-{
- const char *b = pass_alnums(a);
- ZOpcode *op = symtable_lookup2(Opcodes, a, b - a);
- if (!op) return 0;
- ZOpcode_flags flags = op->flags;
- /* !!! TODO !!! */
- return 0;
-}
-
-/*
- * Line can be one from: Comment, Global label, Local label, Directive, Name=Value, Instruction
- */
-int parse_line(const char *p)
-{
- for (; *p; p++) {
- char c = *p;
- int n;
- if (isspace(c)) continue;
- if (iscomment(c)) return 0;
- if (n = tryparse_directive(p)) return n;
- if (n = tryparse_name(p)) return n; // ..label or assignment
- if (n = tryparse_instruction(p)) return n;
- fatal_error("wrong line");
- }
- return 0;
-}
-
-#define MAX_LINESIZE 1024
-
-int parse_file(const char *filename)
-{
- FILE *fp = fopen(filename, "r");
- if (!fp) fatal_error("wrong file");
-
- //const int MAX_LINESIZE = 1024;
- char line[MAX_LINESIZE];
- int newline_missing = 0;
-
- while (fgets(line, MAX_LINESIZE, fp)) {
- if (newline_missing) fatal_error("line too long");
-
- int n = strlen(line);
- if (!n) continue;
-
- parse_line(line);
-
- newline_missing = (line[n-1] != '\n');
- }
-
- close(fp);
-}
-
-/*
-
-line_passed() {
- skip_spaces();
- return (current_token == LINE_END || current_token == LINE_COMMENT);
-}
-
-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)
-}
-
-
-*/
--- /dev/null
+/*
+ * parser.c -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016, 2019 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>
+#include <stdio.h> /* fopen, fgets */
+#include <string.h> /* strlen */
+#include <ctype.h>
+#include <string>
+using namespace std;
+
+
+#include "header.h"
+#include "parser.h"
+
+extern "C"
+{
+#include "directives.h"
+#include "opcodes.h"
+}
+#include "labels.h"
+#include "string_table.h"
+
+
+#define iscomment(c) ((c) == ';')
+#define isbindigit(c) ((c) == '0' || (c) == '1')
+
+/* !!! TODO !!! */
+#define fatal_error(errmsg) printf(errmsg)
+#define PC NULL
+
+unsigned g_numberOfInstructions = 0;
+
+
+ZMemblock (*g_codes[MAX_NUMBER_OF_INSTRUCTIONS]);
+
+
+void
+checksep (const char *p)
+{
+ if (!*p || iscomment (*p) || isspace (*p))
+ return;
+ fatal_error ("wrong chars");
+}
+
+
+const char *
+pass_spaces (const char *p)
+{
+ while (p && isspace (*p))
+ p++;
+ return (p && *p) ? p : NULL;
+}
+
+
+const char *
+pass_alnums (const char *p)
+{
+ while (p && isalnum (*p))
+ p++;
+ return (p && *p) ? p : NULL;
+}
+
+
+int tryparse_instruction (const char *a);
+
+int
+tryparse_directive (const char *p)
+{
+ 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);
+ if (!f)
+ return 0;
+ return (*f) (b);
+}
+
+
+int
+tryparse_assignment (const char *a, const char *b, const char *c)
+{
+ return 0;
+}
+
+
+int
+tryparse_label (const char *a, const char *b, const char *c)
+{
+ if (*(c + 1) != ':')
+ {
+ symtable_add2 (Local_labels, a, b - a, PC);
+ }
+ else if (*(c + 2) != ':')
+ {
+ symtable_add2 (Global_labels, a, b - a, PC);
+ }
+ else
+ {
+ fatal_error ("wrong label type");
+ }
+
+ while (*c++ == ':');
+ if (*c && ((c = pass_spaces (c)) != NULL) && *c)
+ return tryparse_instruction (c);
+ return 1;
+}
+
+
+int
+tryparse_name (const char *a)
+{
+ const char *b = pass_alnums (a);
+ const char *c = pass_spaces (b);
+
+ if (!c)
+ return 0;
+ if (*c == '=')
+ return tryparse_assignment (a, b, c + 1);
+ if (*c == ':')
+ return tryparse_label (a, b, c);
+ return 0;
+}
+
+
+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)
+ {
+ 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;
+ }
+
+ 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)
+ {
+ for (int i = 0; i < mem_additional->used_size; ++i)
+ zmem_putbyte (g_codes[g_numberOfInstructions],
+ mem_additional->contents[i]);
+ zmem_destroy (mem_additional);
+ }
+
+ ++g_numberOfInstructions;
+ return len;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Line can be one from: Comment, Global label, Local label, Directive, Name=Value, Instruction
+ */
+int
+parse_line (const char *p)
+{
+ for (; *p; p++)
+ {
+ char c = *p;
+ int n;
+ if (isspace (c))
+ continue;
+ if (iscomment (c))
+ return 0;
+ if (n = tryparse_directive (p))
+ return n;
+ if (n = tryparse_name (p))
+ return n; // ..label or assignment
+ if (n = tryparse_instruction (p))
+ return n;
+ fatal_error ("wrong line");
+ }
+ return 0;
+}
+
+#define MAX_LINESIZE 1024
+
+int
+parse_file (const char *filename)
+{
+ FILE *fp = fopen (filename, "r");
+ if (!fp)
+ fatal_error ("wrong file");
+
+ //const int MAX_LINESIZE = 1024;
+ char line[MAX_LINESIZE];
+ int newline_missing = 0;
+
+ while (fgets (line, MAX_LINESIZE, fp))
+ {
+ if (newline_missing)
+ fatal_error ("line too long");
+
+ int n = strlen (line);
+ if (!n)
+ continue;
+
+ parse_line (line);
+
+ newline_missing = (line[n - 1] != '\n');
+ }
+
+ fclose (fp);
+ return 0;
+}
+
+/*
+
+line_passed() {
+ skip_spaces();
+ return (current_token == LINE_END || current_token == LINE_COMMENT);
+}
+
+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)
+}
+
+
+*/
+
+
+void
+init_parser ()
+{
+ g_numberOfInstructions = 0;
+}
+
+
+void
+relase_parser ()
+{
+ for (int i = 0; i < g_numberOfInstructions; ++i)
+ {
+ zmem_destroy (g_codes[i]);
+ }
+ g_numberOfInstructions = 0;
+}
/*
* parser.h -- part of ZilUtils/ZilAsm
*
- * Copyright (C) 2016 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019 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
#ifndef ZILASM_PARSER
#define ZILASM_PARSER 1
-int parse_file(const char *filename);
-#endif /* ifndef ZILASM_PARSER */
+struct Instruction
+{
+ Byte *pCodes;
+ int size;
+};
+
+void init_parser ();
+
+int parse_file (const char *filename);
+
+extern unsigned g_numberOfInstructions;
+
+#define MAX_NUMBER_OF_INSTRUCTIONS 65536
+extern ZMemblock (*g_codes[MAX_NUMBER_OF_INSTRUCTIONS]);
+
+#endif /* ifndef ZILASM_PARSER */
--- /dev/null
+/*
+ * string_table.cpp -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2019 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 <stdio.h>
+#include <stdlib.h>
+#include "header.h"
+#include "string_table.h"
+#include <string.h>
+extern "C"
+{
+#include <strings.h>
+}
+
+unsigned
+String_table::add_string_to_string_table (const char *str, ZMemblock * zmb)
+{
+ encrypt_string (str, zmb);
+ return 0;
+}
+
+
+ZMemblock *
+String_table::encrypt_string (const char *str, ZMemblock * zmb)
+{
+ if (!zmb)
+ zmb = zmem_init (strlen (str) * 3);
+
+ int currentCharSet = 0;
+ Byte currentByte = 0;
+ int index = 0;
+ Word w = 0;
+ int numberOfSymbolsInWord = 0;
+ while (index < (int) strlen (str))
+ {
+ char c = str[index];
+ if (c >= 'a' && c <= 'z')
+ {
+ switch (currentCharSet)
+ {
+ case 0:
+ break;
+ case 1:
+ write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, 5); // permanently changes to the zero charset
+ currentCharSet = 0;
+ break;
+ case 2:
+ write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, 4); // permanently changes to the zero charset
+ currentCharSet = 0;
+ break;
+ }
+ write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord,
+ c - 'a' + 6);
+ }
+ else if (c >= 'A' && c <= 'Z')
+ {
+ switch (currentCharSet)
+ {
+ case 0:
+ write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, 4); // temporarily changes to the zero charset
+ break;
+ case 1:
+ break;
+ case 2:
+ write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, 4); // permanently changes to the zero charset
+ currentCharSet = 0;
+ write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, 4); // temporarily changes to the first charset
+ break;
+ }
+ write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord,
+ c - 'A' + 6);
+
+ }
+ else if (c == ' ')
+ {
+ write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, 0);
+ }
+ else
+ {
+ char ar[] = "*0123456789.,!?_#'\"/\\-:()";
+ for (int i = 0; i < (int) strlen (ar); ++i)
+ {
+ if (ar[i] == c)
+ {
+ c = i + 7;
+ break;
+ }
+ }
+
+ switch (currentCharSet)
+ {
+ case 0:
+ write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, 5); // temporarily changes to the second charset
+ break;
+ case 1:
+ write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, 5); // permanently changes to the zero charset
+ currentCharSet = 0;
+ write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, 5); // temporarily changes to the second charset
+ break;
+ case 2:
+ break;
+ }
+ write_one_word_to_string_table (zmb, &w, &numberOfSymbolsInWord, c);
+ }
+
+ ++index;
+ }
+
+ if (numberOfSymbolsInWord != 0)
+ {
+ zmem_putbyte (zmb, (w >> 8) & 255);
+ zmem_putbyte (zmb, w & 255);
+ numberOfSymbolsInWord = 0;
+ w = 0;
+ }
+ zmb->contents[zmb->used_size - 2] |= 0x80;
+
+ return zmb;
+}
+
+void
+String_table::write_one_word_to_string_table (ZMemblock * zmb, Word * w,
+ int *numberOfSymbolsInWord,
+ Byte symbol)
+{
+ int shift = ((2 - *numberOfSymbolsInWord) * 5);
+ *w |= (symbol << shift);
+
+ (*numberOfSymbolsInWord)++;
+
+ if (*numberOfSymbolsInWord == 3)
+ {
+ zmem_putbyte (zmb, (*w >> 8) & 255);
+ zmem_putbyte (zmb, (*w) & 255);
+ *numberOfSymbolsInWord = 0;
+ (*w) = 0;
+ }
+}
--- /dev/null
+/*
+ * string_table.h -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2019 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_STRING_TABLE_
+#define ZILASM_STRING_TABLE_
+
+class String_table
+{
+public:
+ unsigned add_string_to_string_table (const char *str, ZMemblock * zmb);
+
+ static ZMemblock *encrypt_string (const char *str, ZMemblock * zmb);
+
+private:
+ static void write_one_word_to_string_table (ZMemblock * zmb, Word * w,
+ int *numberOfSymbolsInWord,
+ Byte symbol);
+};
+
+#endif
/*
* symtable.c -- part of ZilUtils/ZilAsm
*
- * Copyright (C) 2016 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019 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>
+#include "strings.h"
#include <stdlib.h>
#include <assert.h>
#define FIELD_SIZE(Typ,Field) (sizeof(((Typ*)0)->Field))
-Symtable* symtable_create(unsigned elems_count, unsigned name_size, unsigned elem_size)
+Symtable *
+symtable_create (unsigned elems_count, unsigned name_size, unsigned elem_size)
{
- size_t n = elems_count * (name_size + elem_size) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents);
- Symtable *p = malloc(n);
- assert(p);
- bzero(p, n);
- p->elems_count = elems_count;
- p->name_size = name_size;
- p->elem_size = elem_size;
- return p;
+ //size_t n = elems_count * (name_size + elem_size) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents);
+ //Symtable *p = malloc(n);
+
+ Symtable *p = (Symtable *) malloc (sizeof (Symtable));
+ assert (p);
+ size_t n = elems_count * sizeof (SymtableElem);
+ p->contents = (SymtableElem *) malloc (n);
+ bzero (p->contents, n);
+ p->elems_count = elems_count;
+ p->name_size = name_size;
+ p->elem_size = elem_size;
+ return p;
}
-void symtable_destroy(Symtable *p)
+
+void
+symtable_destroy (Symtable * p)
{
- assert(p);
- free(p);
+ assert (p);
+ for (int i = 0; i > p->elems_count; ++i)
+ {
+ free (p->contents[i].name);
+ free (p->contents[i].value);
+ }
+ free (p->contents);
+ free (p);
}
-static unsigned name2pos(const Symtable *p, const char *name, unsigned namelen)
+
+static unsigned
+name2pos (const Symtable * p, const char *name, unsigned namelen)
{
- assert(p);
- unsigned key = 0;
- while(namelen--)
- key = ((key << 1) | (*name++));
- return key % p->elems_count;
+ assert (p);
+ unsigned key = 0;
+ while (namelen--)
+ key = ((key << 1) | (*name++));
+ return key % p->elems_count;
}
-static char *getsym(const Symtable *p, unsigned pos)
+
+static SymtableElem *
+getsym (const Symtable * p, unsigned pos)
{
- //assert(p); //already checked by caller
- //assert(pos < p->elems_count);
- return ((char*)p) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents) + (pos * p->elem_size);
+ //assert(p); //already checked by caller
+ //assert(pos < p->elems_count);
+ //return ((char*)p) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents) + (pos * p->elem_size);
+ return &p->contents[pos];
}
-void* symtable_lookup2(const Symtable *p, const char *name, unsigned namelen)
-{
- assert(p);
- assert(name);
- assert(namelen > 0);
- assert(namelen < p->name_size);
-
- unsigned start = name2pos(p, name, namelen);
- unsigned pos = start;
-
- do {
- char *s = getsym(p, pos);
- if (!*s)
- return NULL;
- if (!memcmp(name, s, namelen))
- return s + p->name_size;
- if (++pos >= p->elems_count)
- pos = 0;
- } while(pos != start);
+// searches for a element in the symbols table and returns its value
+void *
+symtable_lookup2 (const Symtable * p, const char *name, unsigned namelen)
+{
+ assert (p);
+ assert (name);
+ assert (namelen > 0);
+ assert (namelen < p->name_size);
+
+ unsigned start = name2pos (p, name, namelen);
+ unsigned pos = start;
+
+ do
+ {
+ SymtableElem *s = getsym (p, pos);
+ if (!s->name)
return NULL;
+ if (!memcmp (name, s->name, namelen))
+ return s->value;
+ if (++pos >= p->elems_count)
+ pos = 0;
+ }
+ while (pos != start);
+
+ return NULL;
}
-void* symtable_lookup(const Symtable *p, const char *name)
+
+void *
+symtable_lookup (const Symtable * p, const char *name)
{
- assert(name);
- return symtable_lookup2(p, name, strlen(name));
+ assert (name);
+ return symtable_lookup2 (p, name, strlen (name));
}
-void* symtable_add(Symtable *p, const char *name, void *contents)
+
+void *
+symtable_add (Symtable * p, const char *name, void *value)
{
- assert(name);
- return symtable_add2(p, name, strlen(name), contents);
+ assert (name);
+ return symtable_add2 (p, name, strlen (name), value);
}
-void* symtable_add2(Symtable *p, const char *name, unsigned namelen, void *contents)
+
+void *
+symtable_add2 (Symtable * p, const char *name, unsigned namelen, void *value)
{
- assert(p);
- assert(name);
- assert(namelen > 0 && namelen < p->name_size);
- assert(contents);
-
- unsigned start = name2pos(p, name, namelen);
- unsigned pos = start;
-
- do {
- char *s = getsym(p, pos);
- if (!*s) {
- memcpy(s, name, namelen + 1);
- s[namelen] = '\0';
- memcpy(s + p->name_size, contents, p->elem_size);
- return s + p->name_size;
- }
- if (!memcmp(name, s, namelen) && s[namelen] == '\0') {
- /* TODO!! report error */
- return NULL; /* ..already added */
- }
- if (++pos >= p->elems_count)
- pos = 0;
- } while(pos != start);
-
- /* TODO!! report overflow */
- return NULL;
- /* TODO!!! */
+ assert (p);
+ assert (name);
+ assert (namelen > 0 && namelen < p->name_size);
+ assert (value);
+
+ unsigned start = name2pos (p, name, namelen);
+ unsigned pos = start;
+
+ do
+ {
+ SymtableElem *elem = getsym (p, pos);
+ if (!elem->name)
+ {
+ elem->name = (char *) malloc (namelen + 1);
+ memcpy (elem->name, name, namelen + 1);
+ elem->name[namelen] = '\0';
+ elem->value = malloc (p->elem_size);
+ memcpy (elem->value, value, p->elem_size);
+ return elem;
+ }
+ if (!memcmp (name, elem->name, namelen) && elem->name[namelen] == '\0')
+ {
+ /* TODO!! report error */
+ return NULL; /* ..already added */
+ }
+ if (++pos >= p->elems_count)
+ pos = 0;
+ }
+ while (pos != start);
+
+ /* TODO!! report overflow */
+ return NULL;
+ /* TODO!!! */
}
-static int sortfunc(const void *a, const void *b)
+
+static int
+sortfunc (const void *a, const void *b)
{
- const char *s1 = a;
- const char *s2 = b;
- if (!*s1 && !*s2) return 0;
- if (!*s1) return 1;
- if (!*s2) return -1;
- return strcmp(s1, s2);
+ const char *s1 = (const char *) a;
+ const char *s2 = (const char *) b;
+ if (!*s1 && !*s2)
+ return 0;
+ if (!*s1)
+ return 1;
+ if (!*s2)
+ return -1;
+ return strcmp (s1, s2);
}
-void symtable_sort(Symtable *p)
+
+void
+symtable_sort (Symtable * p)
{
- assert(p);
- qsort(getsym(p, 0), p->elems_count, p->elem_size + p->name_size, sortfunc);
+ assert (p);
+ qsort (getsym (p, 0), p->elems_count, p->elem_size + p->name_size,
+ sortfunc);
}
/* END */
/*
* symtable.h -- part of ZilUtils/ZilAsm
*
- * Copyright (C) 2016 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019 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
#ifndef ZILASM_SYMTABLE
#define ZILASM_SYMTABLE 1
-typedef struct {
- unsigned elems_count;
- unsigned name_size;
- unsigned elem_size;
- char contents[1];
+
+typedef struct
+{
+ char *name;
+ void *value;
+
+} SymtableElem;
+
+typedef struct
+{
+ unsigned elems_count;
+ unsigned name_size;
+ unsigned elem_size;
+ //char* contents;
+ SymtableElem *contents; // table of elements
} Symtable;
-Symtable* symtable_create (unsigned elems_count, unsigned name_size, unsigned elem_size);
-void* symtable_lookup (const Symtable*, const char *name);
-void* symtable_lookup2(const Symtable*, const char *name, unsigned namelen);
-void* symtable_add (Symtable*, const char *name, void *contents);
-void* symtable_add2 (Symtable*, const char *name, unsigned namelen, void *contents);
-void symtable_sort (Symtable*);
-void symtable_destroy(Symtable*);
+Symtable *symtable_create (unsigned elems_count, unsigned name_size,
+ unsigned elem_size);
+void *symtable_lookup (const Symtable *, const char *name);
+void *symtable_lookup2 (const Symtable *, const char *name, unsigned namelen);
+void *symtable_add (Symtable *, const char *name, void *contents);
+void *symtable_add2 (Symtable *, const char *name, unsigned namelen,
+ void *contents);
+void symtable_sort (Symtable *);
+void symtable_destroy (Symtable *);
-#endif /* ifndef ZILASM_SYMTABLE */
+#endif /* ifndef ZILASM_SYMTABLE */
/*
* zmem.c -- part of ZilUtils/ZilAsm
*
- * Copyright (C) 2016 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019 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 <assert.h>
-#include <strings.h> /* bzero */
-#include <stdlib.h> /* malloc, free */
+#include <strings.h> /* bzero */
+
+#include <stdlib.h> /* malloc, free */
#include "zmem.h"
-ZMemblock* zmem_init(unsigned maxsize)
+ZMemblock *
+zmem_init (unsigned maxsize)
{
- ZMemblock *zmb = malloc(sizeof(ZMemblock) + maxsize - 1);
- assert(zmb);
- zmb->allocated_size = maxsize;
- zmb->used_size = 0;
- bzero(&zmb->contents, maxsize);
- return zmb;
+ ZMemblock *zmb = malloc (sizeof (ZMemblock) + maxsize - 1);
+ assert (zmb);
+ zmb->allocated_size = maxsize;
+ zmb->used_size = 0;
+ bzero (&zmb->contents, maxsize);
+ return zmb;
}
-void zmem_destroy(ZMemblock *zmb)
+void
+zmem_destroy (ZMemblock * zmb)
{
- assert(zmb);
- free(zmb);
+ assert (zmb);
+ free (zmb);
}
-void zmem_putbyte(ZMemblock *zmb, unsigned char val)
+void
+zmem_putbyte (ZMemblock * zmb, unsigned char val)
{
- assert(zmb);
- assert(zmb->used_size < zmb->allocated_size);
- zmb->contents[zmb->used_size++] = val;
+ assert (zmb);
+ assert (zmb->used_size < zmb->allocated_size);
+ zmb->contents[zmb->used_size++] = val;
}
#ifndef ZILASM_ZMEM
#define ZILASM_ZMEM 1
-typedef struct {
- unsigned allocated_size;
- unsigned used_size;
- unsigned char contents[1];
+typedef struct
+{
+ unsigned allocated_size;
+ unsigned used_size;
+ unsigned char contents[1];
} ZMemblock;
-extern ZMemblock* zmem_init(unsigned maxsize);
-extern void zmem_destroy(ZMemblock *zmb);
-extern void zmem_putbyte(ZMemblock *zmb, unsigned char val);
+extern ZMemblock *zmem_init (unsigned maxsize);
+extern void zmem_destroy (ZMemblock * zmb);
+extern void zmem_putbyte (ZMemblock * zmb, unsigned char val);
-#endif /* ifndef ZILASM_ZMEM */
+#endif /* ifndef ZILASM_ZMEM */