diff --git a/src/ast/expressions.hpp b/src/ast/expressions.hpp index 4284dc1..0cb9de9 100644 --- a/src/ast/expressions.hpp +++ b/src/ast/expressions.hpp @@ -100,6 +100,54 @@ struct Subscript : Expr } }; +struct Slice : Node +{ + ptr lower; + ptr upper; + ptr step; + Slice(ptr l, ptr u, ptr s) : upper(std::move(u)), lower(std::move(l)), step(std::move(s)) {} + std::string dump(int indent = 0) const override + { + std::ostringstream oss; + oss << indent_str(indent) << "Slice"; + if (lower) + { + oss << "\n" + << indent_str(indent + 1) << "Lower\n"; + oss << lower->dump(indent + 2); + } + if (upper) + { + oss << "\n" + << indent_str(indent + 1) << "Upper\n"; + oss << upper->dump(indent + 2); + } + if (step) + { + oss << "\n" + << indent_str(indent + 1) << "Step\n"; + oss << step->dump(indent + 2); + } + return oss.str(); + } +}; + +struct SliceSubscript : Expr +{ + ptr value; + ptr index; + SliceSubscript(ptr v, ptr i) + : value(std::move(v)), index(std::move(i)) {} + std::string dump(int indent = 0) const override + { + std::ostringstream oss; + oss << indent_str(indent) << "SliceSubscript\n"; + oss << value->dump(indent + 1) << '\n'; + oss << index->dump(indent + 1); + return oss.str(); + } +}; + struct List : Expr { std::vector> elements; diff --git a/src/parser.y b/src/parser.y index 1cc9e15..55d06cc 100644 --- a/src/parser.y +++ b/src/parser.y @@ -53,6 +53,8 @@ %right BIT_AND_ASSIGN BIT_OR_ASSIGN BIT_XOR_ASSIGN LSHIFT_ASSIGN RSHIFT_ASSIGN %type > expr +%type > opt_expr +%type > slice %type > stmt %type >> args %type >> stmt_list @@ -70,12 +72,16 @@ stmt_list: ; stmt: - expr NEWLINE { $$ = std::make_unique(std::move($1)); } - | expr ASSIGN expr NEWLINE { $$ = std::make_unique(std::move($1), std::move($3));} + expr NEWLINE { + $$ = std::make_unique(std::move($1)); + } + | expr ASSIGN expr NEWLINE { + $$ = std::make_unique(std::move($1), std::move($3)); + } | KW_IF expr COLON NEWLINE INDENT stmt_list DEDENT { $$ = std::make_unique(std::move($2), std::move($6), std::vector>()); } - | KW_IF expr COLON NEWLINE INDENT stmt_list DEDENT KW_ELSE COLON NEWLINE INDENT stmt_list DEDENT{ + | KW_IF expr COLON NEWLINE INDENT stmt_list DEDENT KW_ELSE COLON NEWLINE INDENT stmt_list DEDENT { $$ = std::make_unique(std::move($2), std::move($6), std::move($12)); } | KW_FOR IDENTIFIER KW_IN expr COLON NEWLINE INDENT stmt_list DEDENT { @@ -84,25 +90,40 @@ stmt: | KW_DEF IDENTIFIER L_PAREN params R_PAREN COLON NEWLINE INDENT stmt_list DEDENT { $$ = std::make_unique($2, std::move($4), std::move($9)); } - | KW_RETURN expr NEWLINE { $$ = std::make_unique(std::move($2));} + | KW_RETURN expr NEWLINE { + $$ = std::make_unique(std::move($2)); + } ; expr: NUMBER { $$ = std::make_unique($1); } | IDENTIFIER { $$ = std::make_unique($1); } | STRING { $$ = std::make_unique($1); } - | expr PLUS expr { $$ = std::make_unique( - BinaryOperator(BinaryOperator::ADD), - std::move($1), std::move($3)); } - | expr MULTIPLY expr { $$ = std::make_unique( - BinaryOperator(BinaryOperator::MUL), - std::move($1), std::move($3)); } - | L_PAREN expr R_PAREN {$$ = std::move($2); /* #todo: test for precedence*/} + | expr PLUS expr { $$ = std::make_unique( BinaryOperator(BinaryOperator::ADD), std::move($1), std::move($3)); } + | expr MULTIPLY expr { $$ = std::make_unique( BinaryOperator(BinaryOperator::MUL), std::move($1), std::move($3)); } + | expr LT expr { $$ = std::make_unique( BinaryOperator(BinaryOperator::LT) , std::move($1), std::move($3)); } + | expr KW_AND expr { $$ = std::make_unique( BinaryOperator(BinaryOperator::AND) , std::move($1), std::move($3)); } + | expr KW_OR expr { $$ = std::make_unique( BinaryOperator(BinaryOperator::OR) , std::move($1), std::move($3)); } + | expr L_BRACKET expr R_BRACKET { $$ = std::make_unique(std::move($1), std::move($3));} + | expr L_BRACKET slice R_BRACKET{ $$ = std::make_unique(std::move($1), std::move($3)); } + | L_PAREN expr R_PAREN {$$ = std::move($2); } | expr L_PAREN args R_PAREN { $$ = std::make_unique(std::move($1), std::move($3));} | expr DOT IDENTIFIER { $$ = std::make_unique(std::move($1), $3);} | L_BRACKET args R_BRACKET { $$ = std::make_unique(std::move($2));} + | MINUS expr { $$ = std::make_unique(UnaryOperator(UnaryOperator::NEG), std::move($2));} ; +slice: + opt_expr COLON opt_expr + { $$ = std::make_unique(std::move($1), std::move($3), nullptr); } + | opt_expr COLON opt_expr COLON opt_expr + { $$ = std::make_unique(std::move($1), std::move($3), std::move($5)); } + ; + +opt_expr: + { $$ = nullptr;} + | expr { $$ = std::move($1);} + args: /* empty */ { $$ = std::vector>(); } | expr { $$ = std::vector>(); @@ -120,4 +141,4 @@ namespace yy { { std::cerr << "Error: " << msg << "\n"; } -} \ No newline at end of file +} diff --git a/src/scanner.hpp b/src/scanner.hpp index 83e612a..70ab7d5 100644 --- a/src/scanner.hpp +++ b/src/scanner.hpp @@ -24,13 +24,13 @@ public: if (eof_emitted) { - //std::cout << "lex: 0\n"; + // std::cout << "lex: 0\n"; return 0; } if (indent_stack.popDedent()) { - //std::cout << "lex: dedent\n"; + // std::cout << "lex: dedent\n"; return yy::parser::token::TOK_DEDENT; } @@ -43,14 +43,14 @@ public: if (!last_was_newline) { last_was_newline = true; - //std::cout << "lex: newline\n"; + // std::cout << "lex: newline\n"; return yy::parser::token::TOK_NEWLINE; } auto result = indent_stack.closeBlock(); if (result == IndentAction::Dedent) { - //std::cout << "lex: dedent\n"; + // std::cout << "lex: dedent\n"; return yy::parser::token::TOK_DEDENT; } @@ -59,7 +59,7 @@ public: last_was_newline = (token == yy::parser::token::TOK_NEWLINE); - //std::cout << "lex: " << Parser::symbol_name(static_cast(token)) << '\n'; + // std::cout << "lex: " << Parser::symbol_name(static_cast(token)) << '\n'; return token; } diff --git a/test/parser/16.out b/test/parser/16.out index 9151a09..ad562ed 100644 --- a/test/parser/16.out +++ b/test/parser/16.out @@ -1,5 +1,4 @@ Module ExprStmt UnaryOp(-) - Number(5) - + Number(5) \ No newline at end of file diff --git a/test/parser/17.out b/test/parser/17.out index 8c78d71..79c327d 100644 --- a/test/parser/17.out +++ b/test/parser/17.out @@ -1,6 +1,5 @@ Module ExprStmt - Compare(<) + BinOp(<) Number(1) - Number(2) - + Number(2) \ No newline at end of file diff --git a/test/parser/18.out b/test/parser/18.out index adcdae4..6025524 100644 --- a/test/parser/18.out +++ b/test/parser/18.out @@ -1,6 +1,5 @@ Module ExprStmt - BoolOp(and) + BinOp(and) Identifier(x) - Identifier(y) - + Identifier(y) \ No newline at end of file diff --git a/test/parser/19.out b/test/parser/19.out index ca4cb2d..09a8828 100644 --- a/test/parser/19.out +++ b/test/parser/19.out @@ -1,8 +1,7 @@ Module ExprStmt - BoolOp(or) + BinOp(or) Identifier(x) - BoolOp(and) + BinOp(and) Identifier(y) - Identifier(z) - + Identifier(z) \ No newline at end of file diff --git a/test/parser/20.out b/test/parser/20.out index 95e314f..805a51b 100644 --- a/test/parser/20.out +++ b/test/parser/20.out @@ -5,5 +5,4 @@ Module Attribute(.bar) Identifier(foo) Number(1) - Number(2) - + Number(2) \ No newline at end of file diff --git a/test/parser/21.in b/test/parser/21.in index f048faa..a1fd66b 100644 --- a/test/parser/21.in +++ b/test/parser/21.in @@ -1,2 +1 @@ -arr[5] - +arr[5] \ No newline at end of file diff --git a/test/parser/21.out b/test/parser/21.out index 22dec03..a719caf 100644 --- a/test/parser/21.out +++ b/test/parser/21.out @@ -2,5 +2,4 @@ Module ExprStmt Subscript Identifier(arr) - Number(5) - + Number(5) \ No newline at end of file diff --git a/test/parser/22.in b/test/parser/22.in index 98e5660..1dd7280 100644 --- a/test/parser/22.in +++ b/test/parser/22.in @@ -1,2 +1 @@ -arr[1:3] - +arr[1:3] \ No newline at end of file diff --git a/test/parser/22.out b/test/parser/22.out index 17b2c4b..9759bb9 100644 --- a/test/parser/22.out +++ b/test/parser/22.out @@ -1,7 +1,9 @@ Module ExprStmt - Slice + SliceSubscript Identifier(arr) - Number(1) - Number(3) - + Slice + Lower + Number(1) + Upper + Number(3) \ No newline at end of file