From dd39429038e227c9769bee55a8c5b24b81e2fdc2 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Thu, 28 Jun 2018 21:18:15 -0400 Subject: [PATCH] switched to expression based syntax with no statements --- example.src | 74 +++++++++---------- source/parser.c | 186 +++++++++++++++++------------------------------- 2 files changed, 103 insertions(+), 157 deletions(-) diff --git a/example.src b/example.src index f0ebb21..b05e693 100644 --- a/example.src +++ b/example.src @@ -1,47 +1,49 @@ require ("fmt") provide (main) -let const_true bool = true; -let const_false bool = false; -let const_uint int = 123; -let const_string string = ""; +let const_true bool = true +let const_false bool = false +let const_uint int = 123 +let const_string string = "" -var var_true bool = true; -var var_false bool = false; -var var_uint int = 123; -var var_string string = ""; +var var_true bool = true +var var_false bool = false +var var_uint int = 123 +var var_string string = "" -type type_int = int; -type type_intary = int[]; -type type_intaryary = int[][]; -type type_intptrary = int*[]; -type type_intptr = int*; -type type_intptrptr = int**; +type type_int = int +type type_intary = int[] +type type_intaryary = int[][] +type type_intptrary = int*[] +type type_intptr = int* +type type_intptrptr = int** type type_struct = struct { - foo = int; - bar = float; -}; + foo = int + bar = float +} type type_union = union { - foo = int; - bar = float; -}; + foo = int + bar = float +} fun main(args string[]) int { - let foo int = 123; - var bar int = 123; - {} - {123;} - 123; - (123); - foo(); - bar(1); - baz(1,2); - if (123) {} - if 123 {} - if (123) {} else {} - if (123) {} else if (123) {} - if (123) {} else if (123) {} else {} - if 123 {} else if 123 {} else {} - return bar; + let foo int = 123 + var bar int = 123 + {123} + 123 + (123) + foo() + bar(1) + baz(1,2) +# if (123) {} +# if 123 {} +# if (123) {} else {} +# if (123) {} else if (123) {} +# if (123) {} else if (123) {} else {} +# if 123 {} else if 123 {} else {} +# +# fun main(args string[]) int { +# 123 +# } } diff --git a/source/parser.c b/source/parser.c index 281a86c..2225da0 100644 --- a/source/parser.c +++ b/source/parser.c @@ -4,26 +4,19 @@ static void require_list(Parser* p); static void provide_list(Parser* p); static AST* definition_list(Parser* p); -static AST* const_definition(Parser* p, bool constant); +static AST* definition(Parser* p); static AST* type_definition(Parser* p); static AST* func_definition(Parser* p); +static AST* expression(Parser* p); +static AST* constant(Parser* p); static AST* type_expression(Parser* p); static AST* struct_fields(Parser* p); static AST* expression_block(Parser* p); -static AST* statement(Parser* p); -static AST* expression(Parser* p); -static AST* definition(Parser* p, bool constant); -static AST* return_statement(Parser* p); -static AST* if_statement(Parser* p); -static AST* func_expr_list(Parser* p); - -static AST* const_expression(Parser* p); +static AST* if_expression(Parser* p); static AST* identifier(Parser* p); -static AST* function(Parser* p); -static AST* literal(Parser* p); -static AST* expr_block(Parser* p); -static AST* if_stmnt(Parser* p); -static AST* func_app(Parser* p, AST* fn); +static AST* func_expr_list(Parser* p); +static Type* get_typedef(Parser* p, char* typename); +static AST* add_type(Parser* p, AST* ast, char* typename); static AST* token_to_tree(Parser* p, Tok* tok); /* Parsing Routines @@ -108,28 +101,26 @@ static void provide_list(Parser* p) { static AST* definition_list(Parser* p) { while (!matches(p, T_END_FILE)) { - TokType type = peek(p)->type; if (matches(p, T_LET) || matches(p, T_VAR)) { - const_definition(p, (type == T_LET)); + definition(p); } else if (matches(p, T_TYPE)) { type_definition(p); } else if (matches(p, T_FUN)) { func_definition(p); } else { - error(p, "only definitions are allowed at the toplevel"); + error(p, "only definitions are allowed at the top level"); } } return NULL; } -static AST* const_definition(Parser* p, bool constant) { +static AST* definition(Parser* p) { if (!accept(p, T_LET) && !accept(p, T_VAR)) error(p, "constant or variable definition expected"); expect(p, T_ID); type_expression(p); expect(p, '='); - const_expression(p); - expect(p, ';'); + expression(p); return NULL; } @@ -138,7 +129,6 @@ static AST* type_definition(Parser* p) { expect(p, T_ID); expect(p, '='); type_expression(p); - expect(p, ';'); return NULL; } @@ -162,19 +152,45 @@ static AST* func_definition(Parser* p) { return NULL; } -static AST* const_expression(Parser* p) { - AST* expr = NULL; - if (accept(p, '(')) { - expr = const_expression(p); +static AST* expression(Parser* p) { + if (matches(p, '(')) { + expect(p, '('); + expression(p); expect(p, ')'); + } else if (matches(p, '{')) { + expression_block(p); + } else if (matches(p, T_IF)) { + if_expression(p); } else if (matches(p, T_ID)) { - expr = identifier(p); + identifier(p); + if (matches(p, '(')) + func_expr_list(p); } else { - expr = literal(p); + constant(p); } - return expr; + return NULL; } +static AST* constant(Parser* p) { + AST* ret = NULL; + Tok* tok = peek(p); + switch (tok->type) { + case T_BOOL: + case T_CHAR: + case T_STRING: + case T_INT: + case T_FLOAT: + ret = token_to_tree(p, tok); + tok->type = T_NONE; + break; + default: + error(p, "expected an expression"); + } + return ret; +} + +/* Type Expressions + ****************************************************************************/ static AST* type_expression(Parser* p) { if (matches(p, T_STRUCT)) { expect(p, T_STRUCT); @@ -202,89 +218,46 @@ static AST* struct_fields(Parser* p) { expect(p, T_ID); expect(p, '='); type_expression(p); - expect(p, ';'); } while (!matches(p, '}')); expect(p, '}'); return NULL; } +/* Expression Blocks + ****************************************************************************/ static AST* expression_block(Parser* p) { expect(p, '{'); while (!matches(p, '}')) { - statement(p); - } - expect(p, '}'); - return NULL; -} - -static AST* statement(Parser* p) { - if (matches(p, '{')) { - expression_block(p); - } else { if (matches(p, T_LET) || matches(p, T_VAR)) { - definition(p, (peek(p)->type == T_LET)); - } else if (matches(p, T_RETURN)) { - return_statement(p); - } else if (matches(p, T_IF)) { - if_statement(p); -// } else if (matches(p, T_WHILE)) { -// } else if (matches(p, T_FOR)) { -// } else if (matches(p, T_DO)) { -// } else if (matches(p, T_SWITCH)) { -// } else if (matches(p, T_MATCH)) { + definition(p); } else { expression(p); - expect(p, ';'); } } + expect(p, '}'); return NULL; } -static AST* expression(Parser* p) { - AST* expr = NULL; - if (accept(p, '(')) { - expr = expression(p); - expect(p, ')'); - } else if (matches(p, T_ID)) { - expr = identifier(p); - if (matches(p, '(')) - func_expr_list(p); - } else { - expr = literal(p); +static AST* if_expression(Parser* p) { + expect(p, T_IF); + expression(p); // condition + expression(p); // true branch + if (accept(p, T_ELSE)) { + expression(p); // false branch } - return expr; -} - -static AST* definition(Parser* p, bool constant) { - if (!accept(p, T_LET) && !accept(p, T_VAR)) - error(p, "constant or variable definition expected"); - expect(p, T_ID); - type_expression(p); - expect(p, '='); - expression(p); - expect(p, ';'); return NULL; } -static AST* return_statement(Parser* p) { - expect(p, T_RETURN); - expression(p); - expect(p, ';'); - return NULL; -} - -static AST* if_statement(Parser* p) { - expect(p, T_IF); - expression(p); - expression_block(p); - if (accept(p, T_ELSE)) { - if (matches(p, T_IF)) { - if_statement(p); - } else { - expression_block(p); - } +static AST* identifier(Parser* p) { + Tok* tok = peek(p); + if (tok->type == T_ID) { + AST* ast = Ident(tok); + tok->type = T_NONE; + return ast; + } else { + error(p, "Expected an identifier"); + return NULL; } - return NULL; } static AST* func_expr_list(Parser* p) { @@ -302,32 +275,14 @@ static AST* func_expr_list(Parser* p) { return NULL; } - - +/* Helper Functions for Constants + ****************************************************************************/ static Type* get_typedef(Parser* p, char* typename) { Sym* sym = sym_get(&(p->syms), typename); if (!sym) error(p, "unknown type '%s'", typename); return sym->type; } -static AST* literal(Parser* p) { - AST* ret = NULL; - Tok* tok = peek(p); - switch (tok->type) { - case T_BOOL: - case T_CHAR: - case T_STRING: - case T_INT: - case T_FLOAT: - ret = token_to_tree(p, tok); - tok->type = T_NONE; - break; - default: - error(p, "expected an expression"); - } - return ret; -} - static AST* add_type(Parser* p, AST* ast, char* typename) { ast->datatype = get_typedef(p, typename); return ast; @@ -345,14 +300,3 @@ static AST* token_to_tree(Parser* p, Tok* tok) { } } -static AST* identifier(Parser* p) { - Tok* tok = peek(p); - if (tok->type == T_ID) { - AST* ast = Ident(tok); - tok->type = T_NONE; - return ast; - } else { - error(p, "Expected an identifier"); - return NULL; - } -} -- 2.54.0