From: Michael D. Lowis Date: Mon, 18 Jun 2018 15:01:57 +0000 (-0400) Subject: added struct, union, array, and pointer syntax to type expressions X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=4f59d32ee00d8eaf05b71b2a0a19f689af82cd25;p=proto%2Fsclpl.git added struct, union, array, and pointer syntax to type expressions --- diff --git a/example.src b/example.src index f63b04c..b099a28 100644 --- a/example.src +++ b/example.src @@ -6,20 +6,25 @@ 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_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& +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; +}; +type type_union = union { + foo = int; + bar = float; +}; fun main() int { } diff --git a/source/lexer.l b/source/lexer.l index 9916d4b..472c82b 100644 --- a/source/lexer.l +++ b/source/lexer.l @@ -33,12 +33,14 @@ NOSPACE [^ \t\r\n] [ \t\r\n] { /* whitespace is insignificant */ } #.*[\r\n] { /* skip line comments */ } -"require" { return T_REQUIRES; } -"provide" { return T_PROVIDES; } -"let" { return T_LET; } -"var" { return T_VAR; } -"fun" { return T_FUN; } -"type" { return T_TYPE; } +"require" { return T_REQUIRES; } +"provide" { return T_PROVIDES; } +"let" { return T_LET; } +"var" { return T_VAR; } +"fun" { return T_FUN; } +"type" { return T_TYPE; } +"struct" { return T_STRUCT; } +"union" { return T_UNION; } "if" { return T_IF; } "else" { return T_ELSE; } @@ -54,6 +56,7 @@ NOSPACE [^ \t\r\n] "&" { return T_AMP; } "=" { return T_ASSIGN; } ";" { return T_SEMI; } +"*" { return T_MUL; } \\. { Value.character = yytext[1]; return T_CHAR; } \\space { Value.character = ' '; return T_CHAR; } diff --git a/source/parser.c b/source/parser.c index 10952db..c7f646b 100644 --- a/source/parser.c +++ b/source/parser.c @@ -8,6 +8,7 @@ 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* struct_fields(Parser* p); static AST* const_expression(Parser* p); static AST* definition(Parser* p); static AST* expression(Parser* p); @@ -70,12 +71,10 @@ static Tok* expect_val(Parser* p, TokType type) { /* Grammar Definition *****************************************************************************/ AST* toplevel(Parser* p) { - if (matches(p, T_REQUIRES)) { + if (matches(p, T_REQUIRES)) require_list(p); - } - if (matches(p, T_PROVIDES)) { + if (matches(p, T_PROVIDES)) provide_list(p); - } definition_list(p); return NULL; } @@ -160,10 +159,37 @@ static AST* const_expression(Parser* p) { } static AST* type_expression(Parser* p) { - expect(p, T_ID); + if (matches(p, T_STRUCT)) { + expect(p, T_STRUCT); + struct_fields(p); + } else if (matches(p, T_UNION)) { + expect(p, T_UNION); + struct_fields(p); + } else { + expect(p, T_ID); + } + while (matches(p, T_MUL) || matches(p, T_LBRACK)) { + if (matches(p, T_LBRACK)) { + expect(p, T_LBRACK); + expect(p, T_RBRACK); + } else { + expect(p, T_MUL); + } + } return NULL; } +static AST* struct_fields(Parser* p) { + expect(p, T_LBRACE); + do { + expect(p, T_ID); + expect(p, T_ASSIGN); + type_expression(p); + expect(p, T_SEMI); + } while(!matches(p, T_RBRACE)); + expect(p, T_RBRACE); + return NULL; +} diff --git a/source/sclpl.h b/source/sclpl.h index 7c8d3a9..4ecd42a 100644 --- a/source/sclpl.h +++ b/source/sclpl.h @@ -41,10 +41,11 @@ void vec_set(vec_t* vec, size_t index, void* data); *****************************************************************************/ typedef enum { T_NONE, T_ERROR, T_END_FILE, - T_PACKAGE, T_REQUIRES, T_PROVIDES, T_LET, T_VAR, T_FUN, T_TYPE, + T_PACKAGE, T_REQUIRES, T_PROVIDES, T_LET, T_VAR, T_FUN, T_TYPE, T_STRUCT, + T_UNION, 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_COLON, T_AMP, T_IF, T_ELSE, T_ASSIGN, T_SEMI + T_DQUOTE, T_COLON, T_AMP, T_IF, T_ELSE, T_ASSIGN, T_SEMI, T_MUL } TokType; typedef struct {