From ad87228a459813218d4d809cc8e9d59228cb27b5 Mon Sep 17 00:00:00 2001 From: augustin64 Date: Wed, 13 Dec 2023 14:42:29 +0100 Subject: [PATCH] Add for(;;) and fix analysis for UnaryPlus/Minus --- src/analysis.cpp | 6 +++-- src/interpreter.cpp | 4 ++-- src/parser.cpp | 54 ++++++++++++++++++++++++++++++--------------- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/analysis.cpp b/src/analysis.cpp index 25ce0d8..e4916ac 100644 --- a/src/analysis.cpp +++ b/src/analysis.cpp @@ -196,6 +196,8 @@ AnalysisResult analyze(Node &ast, Memory &memory) { if (holds_alternative(res) || !is_arithmetic_type(get(res))) { throw TypeError("Expressions must have arithmetic type", get_node_pos(node.children[1])); } + + return get(res); } break; case NodeType::Declaration: { Token type_token = get(node.children[0]); @@ -205,7 +207,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) { string identifier = get(token.data); if (memory.contains(identifier)) - throw TypeError("Already defined identifier \""+identifier+"\"", token.pos); + throw RuntimeError("Already defined identifier \""+identifier+"\"", token.pos); Type type = try_string_to_type(type_string, type_token.pos); memory.declare(identifier, type); @@ -233,7 +235,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) { Token identifierTok = get(node.children[0]); string identifier = get(identifierTok.data); if (!memory.contains(identifier)) - throw TypeError("Unknown identifier \""+identifier+"\"", identifierTok.pos); + throw RuntimeError("Unknown identifier \""+identifier+"\"", identifierTok.pos); Type type = memory.get(identifier).type; AnalysisResult res = analyze(node.children[1], memory); diff --git a/src/interpreter.cpp b/src/interpreter.cpp index acbc30d..4699ab3 100644 --- a/src/interpreter.cpp +++ b/src/interpreter.cpp @@ -285,7 +285,7 @@ EvalResult eval(Node &ast, Memory &memory) { string typeName = get(typeTok.data); string identifier = get(identifierTok.data); - if (memory.contains(identifier)) + if (memory.contains_top(identifier)) throw RuntimeError("Already defined identifier \""+identifier+"\"", identifierTok.pos); memory.declare(identifier, string_to_type(typeName)); @@ -299,7 +299,7 @@ EvalResult eval(Node &ast, Memory &memory) { string identifier = get(identifierTok.data); EvalResult value = eval(node.children[2], memory); - if (memory.contains(identifier)) + if (memory.contains_top(identifier)) throw RuntimeError("Already defined identifier \""+identifier+"\"", identifierTok.pos); Type type = string_to_type(typeName); diff --git a/src/parser.cpp b/src/parser.cpp index 4974f2a..7b9c65e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -69,13 +69,14 @@ Node parse(vector tokens) { } +vector children; +InnerNode epsilon_node = { + .type=NodeType::Epsilon, + .children=children, + .pos=null_pos +}; + ParseReturn parse_prog(vector tokens) { - vector children; - InnerNode epsilon_node = { - .type=NodeType::Epsilon, - .children=children, - .pos=null_pos - }; Node node = epsilon_node; try { @@ -146,12 +147,6 @@ ParseReturn parse_instruction(vector tokens) { if (tokens.size() < 1 || tokens.back().type != TokenType::Semicolon) throw ParseException(); - vector children; - InnerNode epsilon_node = { - .type=NodeType::Epsilon, - .children=children, - .pos=null_pos - }; tokens.pop_back(); // On enlève le ';' de la liste de tokens return { @@ -258,10 +253,17 @@ ParseReturn parse_statement(vector tokens) { tokens.pop_back(); ParseReturn ret1; - try { - ret1 = parse_expr_statement(tokens); - } catch (const ParseException& pex) { - ret1 = parse_expr(tokens); + if (tokens.size() >= 1 && tokens.back().type == TokenType::Semicolon) { + ret1 = { + .node=epsilon_node, + .tokens=tokens + }; + } else { + try { + ret1 = parse_expr_statement(tokens); + } catch (const ParseException& pex) { + ret1 = parse_expr(tokens); + } } int nb_tok = ret1.tokens.size(); // First ; @@ -273,7 +275,15 @@ ParseReturn parse_statement(vector tokens) { tokens = ret1.tokens; tokens.pop_back(); - ParseReturn ret2 = parse_expr(tokens); + ParseReturn ret2; + if (tokens.size() >= 1 && tokens.back().type == TokenType::Semicolon) { + ret2 = { + .node=epsilon_node, + .tokens=tokens + }; + } else { + ret2 = parse_expr(tokens); + } nb_tok = ret2.tokens.size(); // Second ; if (nb_tok == 0 || ret2.tokens.back().type != TokenType::Semicolon) @@ -284,7 +294,15 @@ ParseReturn parse_statement(vector tokens) { tokens = ret2.tokens; tokens.pop_back(); - ParseReturn ret3 = parse_expr(tokens); + ParseReturn ret3; + if (tokens.size() >= 1 && tokens.back().type == TokenType::RParenthese) { + ret3 = { + .node=epsilon_node, + .tokens=tokens + }; + } else { + ret3 = parse_expr(tokens); + } nb_tok = ret3.tokens.size(); // Closing ) if (nb_tok == 0 || ret3.tokens.back().type != TokenType::RParenthese)