From ee6200a45a5c9b1153999da7e23e1ece69ce201c Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Thu, 29 Apr 2021 11:59:56 -0400 Subject: [PATCH] split up and reorganized files --- cerise/inc/cerise.h | 46 ++++-- cerise/src/{parser.c => grammar.c} | 225 +---------------------------- cerise/src/parse.c | 81 +++++++++++ cerise/src/{emalloc.c => stdlib.c} | 6 +- cerise/src/sym.c | 36 +++++ cerise/src/type_checks.c | 87 +++++++++++ 6 files changed, 250 insertions(+), 231 deletions(-) rename cerise/src/{parser.c => grammar.c} (74%) create mode 100644 cerise/src/parse.c rename cerise/src/{emalloc.c => stdlib.c} (71%) create mode 100644 cerise/src/sym.c create mode 100644 cerise/src/type_checks.c diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 84ee627..ec85ec6 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -4,16 +4,12 @@ #include #include #include +#include #include #include #include #include -void fatal(char* estr); -void* emalloc(size_t size); - -/* Token Types - *****************************************************************************/ typedef enum { NONE = 0, IDENT = 256, @@ -74,8 +70,6 @@ typedef struct { } value; } Tok; -/* Lexer and Parser Types - *****************************************************************************/ typedef struct LexFile { struct LexFile* next; char* path; @@ -155,17 +149,51 @@ static inline void item_dump(Item* a) puts(""); } +// src/stdlib.c +void fatal(char* estr); +void* emalloc(size_t size); + +// src/lex.c void lexfile(Parser* ctx, char* path); void lex(Parser* ctx); void lexprintpos(Parser* p, FILE* file, Tok* tok); + +// src/parse.c +Tok* peek(Parser* p); +void error(Parser* p, const char* fmt, ...); +bool matches(Parser* p, TokType type); +bool matches_oneof(Parser* p, TokType types[]); +bool accept(Parser* p, TokType type); +void expect(Parser* p, TokType type); +Tok* expect_val(Parser* p, TokType type); +char* expect_text(Parser* p, TokType type); +int consume(Parser* p); + +// src/sym.c +Symbol* symbol_new(Parser* p, char* name, int class, bool export); +Symbol* symbol_get(Parser* p, int class, char* name); + +// src/type_checks.c +void check_int(Parser* p, Item* item); +void check_ints(Parser* p, Item* a, Item* b); +void check_real(Parser* p, Item* item); +void check_reals(Parser* p, Item* a, Item* b); +void check_num(Parser* p, Item* a); +void check_nums(Parser* p, Item* a, Item* b); +void check_bool(Parser* p, Item* item); +void check_bools(Parser* p, Item* a, Item* b); +void check_types(Parser* p, Item* a, Item* b); + +// src/grammar.c void compile(char* fname); -/* Code Generation - *****************************************************************************/ +// src/const_ops.c int items_const(Item* a, Item* b); void const_binop(int op, Item* a, Item* b); void const_unop(Parser* p, int op, Item* a); +/* Backend Code Generation + *****************************************************************************/ extern Type BoolType, IntType, RealType, StringType; void codegen_setint(Item* item, Type* type, long long val); diff --git a/cerise/src/parser.c b/cerise/src/grammar.c similarity index 74% rename from cerise/src/parser.c rename to cerise/src/grammar.c index a458a55..58e9411 100644 --- a/cerise/src/parser.c +++ b/cerise/src/grammar.c @@ -8,18 +8,18 @@ #ifdef TRACE static int Indent = 0; #define RULE(name) \ - void name##_actual(Parser* p, Item* item); \ - void name(Parser* p, Item* item) { \ + static void name##_actual(Parser* p, Item* item); \ + static void name(Parser* p, Item* item) { \ printf("%*c-> %s\n", ++Indent * 2, ' ', __func__); \ name##_actual(p, item); \ Indent--; } \ - void name##_actual(Parser* p, Item* item) + static void name##_actual(Parser* p, Item* item) #else #define RULE(name) \ - void name(Parser* p, Item* item) + static void name(Parser* p, Item* item) #endif -/* Default Symbols +/* Default Symbol List *****************************************************************************/ static Symbol BoolSym = { .class = SYM_TYPE, @@ -41,125 +41,6 @@ static Symbol RealSym = { .type = &RealType }; -/* Parsing Routines - *****************************************************************************/ -static Tok* peek(Parser* p) -{ - if (NONE == p->tok.type) - lex(p); - return &(p->tok); -} - -static void error(Parser* parser, const char* fmt, ...) -{ - Tok* tok = peek(parser); - va_list args; - va_start(args, fmt); - lexprintpos(parser, stderr, tok); - fprintf(stderr, " error: "); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); - va_end(args); - exit(1); -} - -static bool matches(Parser* p, TokType type) -{ - return (peek(p)->type == type); -} - -static bool matches_oneof(Parser* p, TokType types[]) -{ - for (int i = 0; types[i] != NONE; i++) - { - if (matches(p, types[i])) - { - return true; - } - } - return false; -} - -static bool accept(Parser* p, TokType type) -{ - if (matches(p, type)) { - p->tok.type = NONE; - return true; - } - return false; -} - -static void expect(Parser* p, TokType type) -{ - if (!accept(p, type)) - error(p, "Unexpected token"); -} - -static Tok* expect_val(Parser* p, TokType type) -{ - static Tok token = {0}; - /* perform the match */ - if (matches(p, type)) { - token = *(peek(p)); - p->tok.type = NONE; - } else { - error(p, "Unexpected token"); - } - return &token; -} - -static char* expect_text(Parser* p, TokType type) -{ - return strdup(expect_val(p, type)->text); -} - -static int consume(Parser* p) -{ - int type = peek(p)->type; - if (!accept(p, type)) - { - error(p, "Unexpected token"); - } - return type; -} - -/* Symbol Table - *****************************************************************************/ -static Symbol* symbol_new(Parser* p, char* name, int class, bool export) -{ - Symbol* sym = calloc(1, sizeof(Symbol)); - sym->name = name; - sym->class = class; - sym->export = export; - sym->next = p->scope; - p->scope = sym; - return sym; -} - -static Symbol* symbol_get(Parser* p, int class, char* name) -{ - Symbol* sym = p->scope; - for (; sym; sym = sym->next) - { - if (!strcmp(sym->name, name)) - { - if (class >= 0 && (int)sym->class != class) - { - switch(class) - { - case SYM_CONST: error(p, "'%s' is not a constant", name); break; - case SYM_VAR: error(p, "'%s' is not a variable", name); break; - case SYM_TYPE: error(p, "'%s' is not a type", name); break; - default: assert(!"unknown identifier type"); break; - } - } - return sym; - } - } - error(p, "unknown identifier '%s'", name); - return NULL; -} - /* Item Handling *****************************************************************************/ static void init_item(Item* item, Symbol* sym) @@ -176,97 +57,8 @@ static void init_item(Item* item, Symbol* sym) item->type = sym->type; } -/* Type Checking - *****************************************************************************/ -static void check_int(Parser* p, Item* item) -{ - if (item->type->form != FORM_INT) - { - error(p, "not an int"); - } -} - -static void check_ints(Parser* p, Item* a, Item* b) -{ - check_int(p, a); - check_int(p, b); -} - -static void check_real(Parser* p, Item* item) -{ - if (item->type->form != FORM_REAL) - { - error(p, "not a real"); - } -} - -static void check_reals(Parser* p, Item* a, Item* b) -{ - check_real(p, a); - check_real(p, b); -} - -static void check_num(Parser* p, Item* a) -{ - if (a->type->form == FORM_REAL) - { - check_real(p, a); - } - else - { - check_int(p, a); - } -} - -static void check_nums(Parser* p, Item* a, Item* b) -{ - if (a->type->form == FORM_REAL) - { - check_reals(p, a, b); - } - else - { - check_ints(p, a, b); - } -} - -static void check_bool(Parser* p, Item* item) -{ - if (item->type->form != FORM_BOOL) - { - error(p, "not an bool"); - } -} - -static void check_bools(Parser* p, Item* a, Item* b) -{ - check_bool(p, a); - check_bool(p, b); -} - -static void check_types(Parser* p, Item* a, Item* b) -{ - if (a->type->form == FORM_REAL) - { - check_reals(p, a, b); - } - else if (a->type->form == FORM_INT) - { - check_ints(p, a, b); - } - else if (a->type->form == FORM_BOOL) - { - check_bools(p, a, b); - } - else - { - error(p, "type mismatch"); - } -} - /* Grammar Definition *****************************************************************************/ - static void expression(Parser* p, Item* item); //RULE(expr_list) @@ -658,13 +450,6 @@ RULE(module) expect(p, END); } codegen_endproc(p); - -// char* ename = expect_text(p, IDENT); -// if (strcmp(sname, ename)) -// { -// error(p, "Expected module name '%s', recieved '%s' instead", sname, ename); -// } -// expect(p, ';'); } static inline char* file_load(char* path) diff --git a/cerise/src/parse.c b/cerise/src/parse.c new file mode 100644 index 0000000..29ed6e1 --- /dev/null +++ b/cerise/src/parse.c @@ -0,0 +1,81 @@ +#include "cerise.h" + +Tok* peek(Parser* p) +{ + if (NONE == p->tok.type) + lex(p); + return &(p->tok); +} + +void error(Parser* p, const char* fmt, ...) +{ + Tok* tok = peek(p); + va_list args; + va_start(args, fmt); + lexprintpos(p, stderr, tok); + fprintf(stderr, " error: "); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + exit(1); +} + +bool matches(Parser* p, TokType type) +{ + return (peek(p)->type == type); +} + +bool matches_oneof(Parser* p, TokType types[]) +{ + for (int i = 0; types[i] != NONE; i++) + { + if (matches(p, types[i])) + { + return true; + } + } + return false; +} + +bool accept(Parser* p, TokType type) +{ + if (matches(p, type)) { + p->tok.type = NONE; + return true; + } + return false; +} + +void expect(Parser* p, TokType type) +{ + if (!accept(p, type)) + error(p, "Unexpected token"); +} + +Tok* expect_val(Parser* p, TokType type) +{ + static Tok token = {0}; + /* perform the match */ + if (matches(p, type)) { + token = *(peek(p)); + p->tok.type = NONE; + } else { + error(p, "Unexpected token"); + } + return &token; +} + +char* expect_text(Parser* p, TokType type) +{ + return strdup(expect_val(p, type)->text); +} + +int consume(Parser* p) +{ + int type = peek(p)->type; + if (!accept(p, type)) + { + error(p, "Unexpected token"); + } + return type; +} diff --git a/cerise/src/emalloc.c b/cerise/src/stdlib.c similarity index 71% rename from cerise/src/emalloc.c rename to cerise/src/stdlib.c index b5203a7..95520ec 100644 --- a/cerise/src/emalloc.c +++ b/cerise/src/stdlib.c @@ -1,11 +1,13 @@ #include "cerise.h" -void fatal(char* estr) { +void fatal(char* estr) +{ perror(estr); exit(1); } -void* emalloc(size_t size) { +void* emalloc(size_t size) +{ void* ptr = malloc(size); if (!ptr) fatal("malloc()"); return ptr; diff --git a/cerise/src/sym.c b/cerise/src/sym.c new file mode 100644 index 0000000..bc5f6fa --- /dev/null +++ b/cerise/src/sym.c @@ -0,0 +1,36 @@ +#include "cerise.h" + +Symbol* symbol_new(Parser* p, char* name, int class, bool export) +{ + Symbol* sym = calloc(1, sizeof(Symbol)); + sym->name = name; + sym->class = class; + sym->export = export; + sym->next = p->scope; + p->scope = sym; + return sym; +} + +Symbol* symbol_get(Parser* p, int class, char* name) +{ + Symbol* sym = p->scope; + for (; sym; sym = sym->next) + { + if (!strcmp(sym->name, name)) + { + if (class >= 0 && (int)sym->class != class) + { + switch(class) + { + case SYM_CONST: error(p, "'%s' is not a constant", name); break; + case SYM_VAR: error(p, "'%s' is not a variable", name); break; + case SYM_TYPE: error(p, "'%s' is not a type", name); break; + default: assert(!"unknown identifier type"); break; + } + } + return sym; + } + } + error(p, "unknown identifier '%s'", name); + return NULL; +} diff --git a/cerise/src/type_checks.c b/cerise/src/type_checks.c new file mode 100644 index 0000000..7301781 --- /dev/null +++ b/cerise/src/type_checks.c @@ -0,0 +1,87 @@ +#include "cerise.h" + +void check_int(Parser* p, Item* item) +{ + if (item->type->form != FORM_INT) + { + error(p, "not an int"); + } +} + +void check_ints(Parser* p, Item* a, Item* b) +{ + check_int(p, a); + check_int(p, b); +} + +void check_real(Parser* p, Item* item) +{ + if (item->type->form != FORM_REAL) + { + error(p, "not a real"); + } +} + +void check_reals(Parser* p, Item* a, Item* b) +{ + check_real(p, a); + check_real(p, b); +} + +void check_num(Parser* p, Item* a) +{ + if (a->type->form == FORM_REAL) + { + check_real(p, a); + } + else + { + check_int(p, a); + } +} + +void check_nums(Parser* p, Item* a, Item* b) +{ + if (a->type->form == FORM_REAL) + { + check_reals(p, a, b); + } + else + { + check_ints(p, a, b); + } +} + +void check_bool(Parser* p, Item* item) +{ + if (item->type->form != FORM_BOOL) + { + error(p, "not an bool"); + } +} + +void check_bools(Parser* p, Item* a, Item* b) +{ + check_bool(p, a); + check_bool(p, b); +} + +void check_types(Parser* p, Item* a, Item* b) +{ + if (a->type->form == FORM_REAL) + { + check_reals(p, a, b); + } + else if (a->type->form == FORM_INT) + { + check_ints(p, a, b); + } + else if (a->type->form == FORM_BOOL) + { + check_bools(p, a, b); + } + else + { + error(p, "type mismatch"); + } +} -- 2.49.0