X-Git-Url: https://jxself.org/git/?p=zilutils.git;a=blobdiff_plain;f=zilasm%2Fparser.cpp;fp=zilasm%2Fparser.cpp;h=b819792a14815b07fa6bc4c866a561df6d699f4f;hp=31e257fd444623db965366e8b293d130f8b79032;hb=633e24778bccbc5f035bdb8516e8cc75c85123d9;hpb=82b0f84ab797141758929d16894d42e12ef79af7 diff --git a/zilasm/parser.cpp b/zilasm/parser.cpp index 31e257f..b819792 100644 --- a/zilasm/parser.cpp +++ b/zilasm/parser.cpp @@ -1,7 +1,7 @@ /* * parser.c -- part of ZilUtils/ZilAsm * - * Copyright (C) 2016, 2019 Jason Self + * Copyright (C) 2016, 2019, 2020 Jason Self * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -23,15 +23,16 @@ #include /* strlen */ #include #include +#include using namespace std; #include "header.h" #include "parser.h" +#include "directives.h" extern "C" { -#include "directives.h" #include "opcodes.h" } #include "labels.h" @@ -42,21 +43,45 @@ extern "C" #define isbindigit(c) ((c) == '0' || (c) == '1') /* !!! TODO !!! */ -#define fatal_error(errmsg) printf(errmsg) +//#define fatal_error(errmsg) printf(errmsg) #define PC NULL -unsigned g_numberOfInstructions = 0; +unsigned g_number_of_instructions = 0; + +unsigned g_currentLineNumber = 0; +//string g_source_directory; +bool g_haveErrors = false; + +stack g_parsing_contexts; ZMemblock (*g_codes[MAX_NUMBER_OF_INSTRUCTIONS]); +string +build_error_message(const char *message) +{ + char buff[300]; + sprintf(buff, "error at %s%s line %d: %s", g_parsing_contexts.top().current_directory.c_str(), + g_parsing_contexts.top().current_file_name.c_str(), g_currentLineNumber, message); + return string(buff); +} + + +void +fatal_error(const char *errmsg) +{ + printf( "%s\n", errmsg); + g_haveErrors = true; +} + + void checksep (const char *p) { if (!*p || iscomment (*p) || isspace (*p)) return; - fatal_error ("wrong chars"); + fatal_error (build_error_message ("wrong chars").c_str()); } @@ -91,7 +116,7 @@ tryparse_directive (const char *p) Directive_handler f = directive_lookup (a, b - a); if (!f) return 0; - return (*f) (b); + return (b-a) + (*f) (b); } @@ -115,7 +140,7 @@ tryparse_label (const char *a, const char *b, const char *c) } else { - fatal_error ("wrong label type"); + fatal_error (build_error_message("wrong label type").c_str()); } while (*c++ == ':'); @@ -144,72 +169,96 @@ tryparse_name (const char *a) int tryparse_instruction (const char *a) { - const char *b = pass_alnums (a); - if (b != a) - { - int len = b ? b - a : strlen (a); - ZOpcode *op = (ZOpcode *) symtable_lookup2 (Opcodes, a, len); - if (!op) - return 0; - ZOpcode_flags flags = op->flags; - /* !!! TODO !!! */ - - - ZMemblock *mem_additional = NULL; - - switch (op->opcode) + bool display_error = false; + int len = 0; + const char *b = pass_alnums(a); + if (b != a) { - case Opcode_CRLF: - case Opcode_PRINT: - case Opcode_QUIT: - break; - - case Opcode_PRINTI: - case Opcode_PRINTR: - { - char *p = (char *) a + len; - p = (char *) pass_spaces (p); - if (*p == '\"') - { - p++; - string str; - while (*p != '\"') - { - str += *p; - ++p; - } - len = p - a; - mem_additional = - String_table::encrypt_string (str.c_str (), NULL); - } - break; - } - default: - fatal_error ("error! instruction not supported"); - return 0; + len = b ? b - a : strlen(a); + ZOpcode *op = (ZOpcode *)symtable_lookup2(Opcodes, a, len); + if (op) + { + ZOpcode_flags flags = op->flags; + ZMemblock *mem_additional = NULL; + + switch (op->opcode) + { + case Opcode_CRLF: + case Opcode_PRINT: + case Opcode_QUIT: + break; + + case Opcode_PRINTI: + case Opcode_PRINTR: + { + char *p = (char *)a + len; + p = (char *)pass_spaces(p); + if (*p == '\"') + { + p++; + string str; + while (*p != '\"') + { + str += *p; + ++p; + } + len = p - a; + mem_additional = + String_table::encrypt_string(str.c_str(), NULL); + } + break; + } + default: + { + display_error = true; + } + } + + + if (display_error == false) + { + + int instruction_size = 1; + if (mem_additional) + instruction_size += mem_additional->used_size; + + g_codes[g_number_of_instructions] = zmem_init(instruction_size); + zmem_putbyte(g_codes[g_number_of_instructions], op->opcode); + + if (mem_additional) + { + for (int i = 0; i < mem_additional->used_size; ++i) + zmem_putbyte(g_codes[g_number_of_instructions], + mem_additional->contents[i]); + zmem_destroy(mem_additional); + } + + ++g_number_of_instructions; + return len; + } + } + else + { + //display_error = true; + string message = "wrong line \"" + string(a) + string("\""); + fatal_error(build_error_message(message.c_str()).c_str()); + } } - int instruction_size = 1; - if (mem_additional) - instruction_size += mem_additional->used_size; - //printf("instruction %s", a); - - g_codes[g_numberOfInstructions] = zmem_init (instruction_size); - zmem_putbyte (g_codes[g_numberOfInstructions], op->opcode); - - if (mem_additional) + if (display_error) { - for (int i = 0; i < mem_additional->used_size; ++i) - zmem_putbyte (g_codes[g_numberOfInstructions], - mem_additional->contents[i]); - zmem_destroy (mem_additional); + char buff[300]; + if (len == 0) + len = strlen(a); + char *instrcution_name = (char *)malloc(len + 1); + memcpy(instrcution_name, a, len); + instrcution_name[len] = 0; + string message = "instruction " + string(instrcution_name) + string(" is not supported yet"); + fatal_error(build_error_message(message.c_str()).c_str()); + free(instrcution_name); } - ++g_numberOfInstructions; - return len; - } - - return 0; + return strlen(a); } @@ -233,7 +282,7 @@ parse_line (const char *p) return n; // ..label or assignment if (n = tryparse_instruction (p)) return n; - fatal_error ("wrong line"); + //fatal_error ("wrong line"); } return 0; } @@ -241,32 +290,49 @@ parse_line (const char *p) #define MAX_LINESIZE 1024 int -parse_file (const char *filename) +parse_file (/*const char *filename*/) { - FILE *fp = fopen (filename, "r"); - if (!fp) - fatal_error ("wrong file"); + if (g_parsing_contexts.size() > 0) + { + string filename = g_parsing_contexts.top().current_directory + g_parsing_contexts.top().current_file_name; - //const int MAX_LINESIZE = 1024; - char line[MAX_LINESIZE]; - int newline_missing = 0; + FILE *fp = fopen(filename.c_str(), "r"); + if (fp) + { - while (fgets (line, MAX_LINESIZE, fp)) - { - if (newline_missing) - fatal_error ("line too long"); + g_currentLineNumber = 0; - int n = strlen (line); - if (!n) - continue; + //const int MAX_LINESIZE = 1024; + char line[MAX_LINESIZE]; + int newline_missing = 0; - parse_line (line); + while (g_stopParsing == 0 && fgets(line, MAX_LINESIZE, fp)) + { + ++g_currentLineNumber; - newline_missing = (line[n - 1] != '\n'); - } + if (newline_missing) + fatal_error(build_error_message("line too long").c_str()); - fclose (fp); - return 0; + int n = strlen(line); + if (!n) + continue; + + parse_line(line); + + newline_missing = (line[n - 1] != '\n'); + } + + fclose(fp); + } + else + { + string message = string("can't open file ") + filename; + fatal_error(message.c_str()); + } + + g_parsing_contexts.pop(); + } + return 0; } /* @@ -298,16 +364,19 @@ if (current_token == DIRECTIVE) { void init_parser () { - g_numberOfInstructions = 0; + g_number_of_instructions = 0; } + + + void relase_parser () { - for (int i = 0; i < g_numberOfInstructions; ++i) + for (int i = 0; i < g_number_of_instructions; ++i) { zmem_destroy (g_codes[i]); } - g_numberOfInstructions = 0; + g_number_of_instructions = 0; }