From: Michael D. Lowis Date: Sat, 2 Jun 2018 02:11:20 +0000 (-0400) Subject: added codegen module and code to register bindings with symbol table X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=7c45e85d763f457a3ce1c9fb078b34664644beab;p=proto%2Fsclpl.git added codegen module and code to register bindings with symbol table --- diff --git a/Makefile b/Makefile index cf7d517..26c031d 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,8 @@ OBJS = source/main.o \ source/lexer.o \ source/ast.o \ source/types.o \ - source/syms.o + source/syms.o \ + source/codegen.o .PHONY: all tests specs all: sclpl tests specs diff --git a/source/codegen.c b/source/codegen.c new file mode 100644 index 0000000..b16fdfa --- /dev/null +++ b/source/codegen.c @@ -0,0 +1,19 @@ +#include + +void codegen_init(Parser* p) { + sym_add(&(p->syms), SF_TYPEDEF, "void", VoidType()); + sym_add(&(p->syms), SF_TYPEDEF, "bool", UIntType(1u)); + sym_add(&(p->syms), SF_TYPEDEF, "byte", UIntType(8u)); + sym_add(&(p->syms), SF_TYPEDEF, "uint", UIntType(64u)); + sym_add(&(p->syms), SF_TYPEDEF, "u8", UIntType(8u)); + sym_add(&(p->syms), SF_TYPEDEF, "u16", UIntType(16u)); + sym_add(&(p->syms), SF_TYPEDEF, "u32", UIntType(32u)); + sym_add(&(p->syms), SF_TYPEDEF, "u64", UIntType(64u)); + sym_add(&(p->syms), SF_TYPEDEF, "int", IntType(64u)); + sym_add(&(p->syms), SF_TYPEDEF, "i8", IntType(8u)); + sym_add(&(p->syms), SF_TYPEDEF, "i16", IntType(16u)); + sym_add(&(p->syms), SF_TYPEDEF, "i32", IntType(32u)); + sym_add(&(p->syms), SF_TYPEDEF, "i64", IntType(64u)); + sym_add(&(p->syms), SF_TYPEDEF, "string", + ArrayOf(sym_get(&(p->syms), "byte")->type, -1)); +} diff --git a/source/main.c b/source/main.c index adc3d7a..69918a4 100644 --- a/source/main.c +++ b/source/main.c @@ -3,26 +3,6 @@ char* ARGV0; char* Artifact = "ast"; -/* Builtin Types - *****************************************************************************/ -static void builtins(Parser* p) { - sym_addtype(&(p->syms), "void", VoidType()); - sym_addtype(&(p->syms), "bool", UIntType(1u)); - sym_addtype(&(p->syms), "byte", UIntType(8u)); - sym_addtype(&(p->syms), "uint", UIntType(64u)); - sym_addtype(&(p->syms), "u8", UIntType(8u)); - sym_addtype(&(p->syms), "u16", UIntType(16u)); - sym_addtype(&(p->syms), "u32", UIntType(32u)); - sym_addtype(&(p->syms), "u64", UIntType(64u)); - sym_addtype(&(p->syms), "int", IntType(64u)); - sym_addtype(&(p->syms), "i8", IntType(8u)); - sym_addtype(&(p->syms), "i16", IntType(16u)); - sym_addtype(&(p->syms), "i32", IntType(32u)); - sym_addtype(&(p->syms), "i64", IntType(64u)); - sym_addtype(&(p->syms), "string", - ArrayOf(sym_get(&(p->syms), "byte")->type, -1)); -} - /* Driver Modes *****************************************************************************/ static int emit_tokens(void) { @@ -41,7 +21,7 @@ static int emit_tokens(void) { static int emit_ast(void) { AST* tree = NULL; Parser ctx = { .input = stdin }; - builtins(&ctx); + codegen_init(&ctx); while(NULL != (tree = toplevel(&ctx))) pprint_tree(stdout, tree, 0); return 0; @@ -77,7 +57,7 @@ int main(int argc, char **argv) { } else if (0 == strcmp("bin", Artifact)) { return emit_binary(); } else { - fprintf(stderr, "Unknonwn artifact type: '%s'\n\n", Artifact); + fprintf(stderr, "Unknown artifact type: '%s'\n\n", Artifact); usage(); } return 1; diff --git a/source/parser.c b/source/parser.c index 746272a..10f0a8d 100644 --- a/source/parser.c +++ b/source/parser.c @@ -1,4 +1,5 @@ #include +#include static AST* const_definition(Parser* p, bool constant); static AST* const_expression(Parser* p); @@ -21,9 +22,14 @@ static Tok* peek(Parser* p) { return &(p->tok); } -static void error(Parser* parser, const char* text) { +static void error(Parser* parser, const char* fmt, ...) { Tok* tok = peek(parser); - fprintf(stderr, ":%zu:%zu:Error: %s\n", tok->line, tok->col, text); + va_list args; + va_start(args, fmt); + fprintf(stderr, ":%zu:%zu: error: ", tok->line, tok->col); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); exit(1); } @@ -76,11 +82,11 @@ AST* toplevel(Parser* p) { } static AST* const_definition(Parser* p, bool constant) { - AST* expr; Tok* id = expect_val(p, T_ID); - type_annotation(p); + Type* type = type_annotation(p); expect(p, T_ASSIGN); - expr = const_expression(p); + AST* expr = const_expression(p); + sym_add(&(p->syms), (constant ? SF_CONSTANT : 0), id->value.text, type); return Var(id, expr, constant); } @@ -98,8 +104,10 @@ static AST* const_expression(Parser* p) { } static Type* type_annotation(Parser* p) { - expect(p, T_ID); - return NULL; + Tok* id = expect_val(p, T_ID); + Sym* sym = sym_get(&(p->syms), id->value.text); + if (!sym) error(p, "unknown type '%s'", id->value.text); + return sym->type; } static AST* literal(Parser* p) { diff --git a/source/sclpl.h b/source/sclpl.h index 69df984..1549da5 100644 --- a/source/sclpl.h +++ b/source/sclpl.h @@ -87,9 +87,15 @@ Type* PtrTo(Type* type); /* Symbol Table *****************************************************************************/ +typedef enum { + SF_TYPEDEF = (1 << 0), + SF_CONSTANT = (1 << 1), +} SymFlags; + typedef struct Sym { struct Sym* next; bool is_typedef; + int flags; char* name; Type* type; } Sym; @@ -98,8 +104,7 @@ typedef struct { Sym* syms; } SymTable; -void sym_adddef(SymTable* syms, char* name, Type* type); -void sym_addtype(SymTable* syms, char* name, Type* type); +void sym_add(SymTable* syms, int flags, char* name, Type* type); Sym* sym_get(SymTable* syms, char* name); /* AST Types @@ -182,6 +187,7 @@ typedef struct { void gettoken(Parser* ctx, Tok* tok); AST* toplevel(Parser* p); +void codegen_init(Parser* p); /* Option Parsing *****************************************************************************/ diff --git a/source/syms.c b/source/syms.c index 0ba2934..6a8f0e2 100644 --- a/source/syms.c +++ b/source/syms.c @@ -1,20 +1,16 @@ #include -Sym* mksym(char* name, Type* type, bool is_typedef, Sym* next) { +static Sym* mksym(int flags, char* name, Type* type, Sym* next) { Sym* sym = emalloc(sizeof(Sym)); + sym->flags = flags; sym->name = name; sym->type = type; - sym->is_typedef = is_typedef; sym->next = next; return sym; } -void sym_adddef(SymTable* syms, char* name, Type* type) { - syms->syms = mksym(name, type, false, syms->syms); -} - -void sym_addtype(SymTable* syms, char* name, Type* type) { - syms->syms = mksym(name, type, true, syms->syms); +void sym_add(SymTable* syms, int flags, char* name, Type* type) { + syms->syms = mksym(flags, name, type, syms->syms); } Sym* sym_get(SymTable* syms, char* name) {