From: Michael D. Lowis Date: Thu, 14 Jun 2018 16:36:37 +0000 (-0400) Subject: added line comments and fleshed out parser a bit more X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=18cc1b145e22d80f6f482a35a946e9ec59f830b6;p=proto%2Fsclpl.git added line comments and fleshed out parser a bit more --- diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e69de29..0000000 diff --git a/example.src b/example.src index 57ee08c..1d63d64 100644 --- a/example.src +++ b/example.src @@ -12,4 +12,15 @@ var const_false bool = false var const_uint int = 123 var const_string string = "" +# type type_int int +# type type_intary int[] +# type type_intary42 int[42] +# type type_intaryary int[][] +# type type_intptrary int*[] +# type type_intrefary int&[] +# type type_intptr int* +# type type_intptrptr int** +# type type_intref int& + + diff --git a/source/lexer.l b/source/lexer.l index e48131c..659355b 100644 --- a/source/lexer.l +++ b/source/lexer.l @@ -31,6 +31,8 @@ NOSPACE [^ \t\r\n] %% [ \t\r\n] { /* whitespace is insignificant */ } +#.*[\r\n] { /* skip line comments */ } + <> { return T_END_FILE; } "package" { return T_PACKAGE; } @@ -41,16 +43,13 @@ NOSPACE [^ \t\r\n] "fun" { return T_FUN; } "if" { return T_IF; } -"then" { return T_THEN; } "else" { return T_ELSE; } -"end" { return T_END; } "(" { return T_LPAR; } ")" { return T_RPAR; } "[" { return T_LBRACK; } "]" { return T_RBRACK; } "{" { return T_LBRACE; } "}" { return T_RBRACE; } -";" { return T_END; } "," { return T_COMMA; } "'" { return T_SQUOTE; } ":" { return T_COLON; } diff --git a/source/parser.c b/source/parser.c index 1f3cb1f..39ac254 100644 --- a/source/parser.c +++ b/source/parser.c @@ -7,6 +7,7 @@ static AST* definition_list(Parser* p); static AST* const_definition(Parser* p, bool constant); static AST* type_definition(Parser* p); static AST* func_definition(Parser* p); +static AST* type_expression(Parser* p); static AST* const_expression(Parser* p); static AST* definition(Parser* p); static AST* expression(Parser* p); @@ -38,31 +39,31 @@ static void error(Parser* parser, const char* fmt, ...) { exit(1); } -static bool match(Parser* parser, TokType type) { - return (peek(parser)->type == type); +static bool matches(Parser* p, TokType type) { + return (peek(p)->type == type); } -static bool accept(Parser* parser, TokType type) { - if (peek(parser)->type == type) { - parser->tok.type = T_NONE; +static bool accept(Parser* p, TokType type) { + if (matches(p, type)) { + p->tok.type = T_NONE; return true; } return false; } -static void expect(Parser* parser, TokType type) { - if (!accept(parser, type)) - error(parser, "Unexpected token"); +static void expect(Parser* p, TokType type) { + if (!accept(p, type)) + error(p, "Unexpected token"); } -static Tok* expect_val(Parser* parser, TokType type) { +static Tok* expect_val(Parser* p, TokType type) { Tok* tok = NULL; - if (peek(parser)->type == type) { + if (matches(p, type)) { tok = calloc(1, sizeof(Tok)); - *tok = *(peek(parser)); - parser->tok.type = T_NONE; + *tok = *(peek(p)); + p->tok.type = T_NONE; } else { - error(parser, "Unexpected token"); + error(p, "Unexpected token"); } return tok; } @@ -73,17 +74,19 @@ static Tok* expect_val(Parser* parser, TokType type) { AST* toplevel(Parser* p) { expect(p, T_PACKAGE); expect(p, T_ID); - if (accept(p, T_REQUIRES)) + if (accept(p, T_REQUIRES)) { require_list(p); - if (accept(p, T_PROVIDES)) + } + if (accept(p, T_PROVIDES)) { provide_list(p); + } definition_list(p); return NULL; } static void require_list(Parser* p) { expect(p, T_LPAR); - while (peek(p)->type != T_RPAR) { + while (!matches(p, T_RPAR)) { expect(p, T_STRING); } expect(p, T_RPAR); @@ -91,14 +94,14 @@ static void require_list(Parser* p) { static void provide_list(Parser* p) { expect(p, T_LPAR); - while (peek(p)->type != T_RPAR) { + while (!matches(p, T_RPAR)) { expect(p, T_ID); } expect(p, T_RPAR); } static AST* definition_list(Parser* p) { - while (!match(p, T_END_FILE)) { + while (!matches(p, T_END_FILE)) { TokType type = peek(p)->type; if (accept(p, T_LET) || accept(p, T_VAR)) { const_definition(p, (type == T_LET)); @@ -125,12 +128,14 @@ static AST* const_definition(Parser* p, bool constant) { } static AST* type_definition(Parser* p) { + expect(p, T_TYPE); + expect(p, T_ID); + type_expression(p); return NULL; } static AST* func_definition(Parser* p) { return NULL; - } static AST* const_expression(Parser* p) { @@ -138,7 +143,7 @@ static AST* const_expression(Parser* p) { if (accept(p, T_LPAR)) { expr = const_expression(p); expect(p, T_RPAR); - } else if (match(p, T_ID)) { + } else if (matches(p, T_ID)) { expr = identifier(p); } else { expr = literal(p); @@ -146,6 +151,24 @@ static AST* const_expression(Parser* p) { return expr; } +static AST* type_expression(Parser* p) { + expect(p, T_ID); + return NULL; +} + + + + + + + + + + + + + + static Type* get_typedef(Parser* p, char* typename) { Sym* sym = sym_get(&(p->syms), typename); if (!sym) error(p, "unknown type '%s'", typename); diff --git a/source/pprint.c b/source/pprint.c index f47fe8b..ac01cea 100644 --- a/source/pprint.c +++ b/source/pprint.c @@ -20,7 +20,6 @@ static const char* token_type_to_string(TokType type) { case T_RPAR: return "T_RPAR"; case T_COMMA: return "T_COMMA"; case T_ID: return "T_ID"; - case T_END: return "T_END"; case T_COLON: return "T_COLON"; case T_AMP: return "T_AMP"; case T_SQUOTE: return "T_SQUOTE"; diff --git a/source/sclpl.h b/source/sclpl.h index 5851cfa..c8e8e5d 100644 --- a/source/sclpl.h +++ b/source/sclpl.h @@ -44,7 +44,7 @@ typedef enum { T_PACKAGE, T_REQUIRES, T_PROVIDES, T_LET, T_VAR, T_FUN, T_TYPE, T_ID, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_STRING, T_LBRACE, T_RBRACE, T_LBRACK, T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_SQUOTE, - T_DQUOTE, T_END, T_COLON, T_AMP, T_IF, T_THEN, T_ELSE, T_ASSIGN + T_DQUOTE, T_COLON, T_AMP, T_IF, T_ELSE, T_ASSIGN } TokType; typedef struct { diff --git a/spec/lexer_spec.rb b/spec/lexer_spec.rb index 8936dbc..1a7c93c 100644 --- a/spec/lexer_spec.rb +++ b/spec/lexer_spec.rb @@ -34,18 +34,14 @@ describe "lexer" do expect(lexer(',')).to eq ['T_COMMA'] end - it "should recognize ;" do - expect(lexer(';')).to eq ['T_END'] - end - it "should recognize :" do expect(lexer(':')).to eq ['T_COLON'] end it "should recognize all punctuation" do - expect(lexer('[](){}\',;')).to eq( + expect(lexer('[](){}\',')).to eq( ["T_LBRACK", "T_RBRACK", "T_LPAR", "T_RPAR", "T_LBRACE", "T_RBRACE", - "T_SQUOTE", "T_COMMA", "T_END"]) + "T_SQUOTE", "T_COMMA"]) end it "should recognize [ after an identifier" do @@ -81,7 +77,7 @@ describe "lexer" do end it "should recognize } after an identifier" do - expect(lexer('foo;')).to eq(['T_ID:foo', 'T_END']) + expect(lexer('foo')).to eq(['T_ID:foo']) end end