Add for(;;) and fix analysis for UnaryPlus/Minus

This commit is contained in:
augustin64 2023-12-13 14:42:29 +01:00
parent 1d571f36b1
commit ad87228a45
3 changed files with 42 additions and 22 deletions

View File

@ -196,6 +196,8 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
if (holds_alternative<monostate>(res) || !is_arithmetic_type(get<Type>(res))) { if (holds_alternative<monostate>(res) || !is_arithmetic_type(get<Type>(res))) {
throw TypeError("Expressions must have arithmetic type", get_node_pos(node.children[1])); throw TypeError("Expressions must have arithmetic type", get_node_pos(node.children[1]));
} }
return get<Type>(res);
} break; } break;
case NodeType::Declaration: { case NodeType::Declaration: {
Token type_token = get<Token>(node.children[0]); Token type_token = get<Token>(node.children[0]);
@ -205,7 +207,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
string identifier = get<string>(token.data); string identifier = get<string>(token.data);
if (memory.contains(identifier)) 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); Type type = try_string_to_type(type_string, type_token.pos);
memory.declare(identifier, type); memory.declare(identifier, type);
@ -233,7 +235,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
Token identifierTok = get<Token>(node.children[0]); Token identifierTok = get<Token>(node.children[0]);
string identifier = get<string>(identifierTok.data); string identifier = get<string>(identifierTok.data);
if (!memory.contains(identifier)) if (!memory.contains(identifier))
throw TypeError("Unknown identifier \""+identifier+"\"", identifierTok.pos); throw RuntimeError("Unknown identifier \""+identifier+"\"", identifierTok.pos);
Type type = memory.get(identifier).type; Type type = memory.get(identifier).type;
AnalysisResult res = analyze(node.children[1], memory); AnalysisResult res = analyze(node.children[1], memory);

View File

@ -285,7 +285,7 @@ EvalResult eval(Node &ast, Memory &memory) {
string typeName = get<string>(typeTok.data); string typeName = get<string>(typeTok.data);
string identifier = get<string>(identifierTok.data); string identifier = get<string>(identifierTok.data);
if (memory.contains(identifier)) if (memory.contains_top(identifier))
throw RuntimeError("Already defined identifier \""+identifier+"\"", identifierTok.pos); throw RuntimeError("Already defined identifier \""+identifier+"\"", identifierTok.pos);
memory.declare(identifier, string_to_type(typeName)); memory.declare(identifier, string_to_type(typeName));
@ -299,7 +299,7 @@ EvalResult eval(Node &ast, Memory &memory) {
string identifier = get<string>(identifierTok.data); string identifier = get<string>(identifierTok.data);
EvalResult value = eval(node.children[2], memory); EvalResult value = eval(node.children[2], memory);
if (memory.contains(identifier)) if (memory.contains_top(identifier))
throw RuntimeError("Already defined identifier \""+identifier+"\"", identifierTok.pos); throw RuntimeError("Already defined identifier \""+identifier+"\"", identifierTok.pos);
Type type = string_to_type(typeName); Type type = string_to_type(typeName);

View File

@ -69,13 +69,14 @@ Node parse(vector<Token> tokens) {
} }
vector<Node> children;
InnerNode epsilon_node = {
.type=NodeType::Epsilon,
.children=children,
.pos=null_pos
};
ParseReturn parse_prog(vector<Token> tokens) { ParseReturn parse_prog(vector<Token> tokens) {
vector<Node> children;
InnerNode epsilon_node = {
.type=NodeType::Epsilon,
.children=children,
.pos=null_pos
};
Node node = epsilon_node; Node node = epsilon_node;
try { try {
@ -146,12 +147,6 @@ ParseReturn parse_instruction(vector<Token> tokens) {
if (tokens.size() < 1 || tokens.back().type != TokenType::Semicolon) if (tokens.size() < 1 || tokens.back().type != TokenType::Semicolon)
throw ParseException(); throw ParseException();
vector<Node> children;
InnerNode epsilon_node = {
.type=NodeType::Epsilon,
.children=children,
.pos=null_pos
};
tokens.pop_back(); // On enlève le ';' de la liste de tokens tokens.pop_back(); // On enlève le ';' de la liste de tokens
return { return {
@ -258,10 +253,17 @@ ParseReturn parse_statement(vector<Token> tokens) {
tokens.pop_back(); tokens.pop_back();
ParseReturn ret1; ParseReturn ret1;
try { if (tokens.size() >= 1 && tokens.back().type == TokenType::Semicolon) {
ret1 = parse_expr_statement(tokens); ret1 = {
} catch (const ParseException& pex) { .node=epsilon_node,
ret1 = parse_expr(tokens); .tokens=tokens
};
} else {
try {
ret1 = parse_expr_statement(tokens);
} catch (const ParseException& pex) {
ret1 = parse_expr(tokens);
}
} }
int nb_tok = ret1.tokens.size(); // First ; int nb_tok = ret1.tokens.size(); // First ;
@ -273,7 +275,15 @@ ParseReturn parse_statement(vector<Token> tokens) {
tokens = ret1.tokens; tokens = ret1.tokens;
tokens.pop_back(); 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 ; nb_tok = ret2.tokens.size(); // Second ;
if (nb_tok == 0 || ret2.tokens.back().type != TokenType::Semicolon) if (nb_tok == 0 || ret2.tokens.back().type != TokenType::Semicolon)
@ -284,7 +294,15 @@ ParseReturn parse_statement(vector<Token> tokens) {
tokens = ret2.tokens; tokens = ret2.tokens;
tokens.pop_back(); 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 ) nb_tok = ret3.tokens.size(); // Closing )
if (nb_tok == 0 || ret3.tokens.back().type != TokenType::RParenthese) if (nb_tok == 0 || ret3.tokens.back().type != TokenType::RParenthese)