From 3402ff684c4c4409f5859a813770abc5e672877c Mon Sep 17 00:00:00 2001 From: RedoC-github Date: Tue, 25 Jan 2022 19:46:10 +0900 Subject: [PATCH 1/6] update error event --- src/error/signal.h | 8 ++- src/import_/eexec_.cpp | 4 +- src/interpreter.cpp | 4 +- src/parser/parse.cpp | 149 +++++++++++++++++++++-------------------- src/runtime/AST.h | 41 +++++++----- src/type/variable.h | 72 ++++++++++---------- 6 files changed, 146 insertions(+), 132 deletions(-) diff --git a/src/error/signal.h b/src/error/signal.h index 86f23fb..2f6c358 100644 --- a/src/error/signal.h +++ b/src/error/signal.h @@ -20,8 +20,12 @@ enum Err { class ErrHandler { public: - void CallErr(std::string errmsg) { - std::cout << "\e[31m" << errmsg << "\e[m"; + void CallErr(int error_pos, std::string errmsg) { + if (error_pos != -1) { + std::cout << "\e[31m"<< "line " << error_pos << ": " << errmsg << "\e[m"; + exit(1); + } + std::cout << "\e[31m"<< "runtime: " << errmsg << "\e[m"; exit(1); return; } diff --git a/src/import_/eexec_.cpp b/src/import_/eexec_.cpp index 836f596..9a75128 100644 --- a/src/import_/eexec_.cpp +++ b/src/import_/eexec_.cpp @@ -17,7 +17,7 @@ ArrayWithCode EExecFunc(std::string func, Array argv) { void* handle = dlopen("lib/library.so", RTLD_LAZY); if (!handle) { - ErrHandler().CallErr("Cannot load library: " + std::string(dlerror())); + ErrHandler().CallErr(-1, "Cannot load library: " + std::string(dlerror())); return {null, ERROR}; } @@ -31,7 +31,7 @@ ArrayWithCode EExecFunc(std::string func, Array argv) { t fptr = (t) dlsym(handle, exfunc.c_str()); const char *dlsym_error = dlerror(); if (dlsym_error) { - ErrHandler().CallErr("Cannot load symbol: " + func); + ErrHandler().CallErr(-1, "Cannot load symbol: " + func); dlclose(handle); return {null, ERROR}; } diff --git a/src/interpreter.cpp b/src/interpreter.cpp index bdc8553..e02e0b5 100644 --- a/src/interpreter.cpp +++ b/src/interpreter.cpp @@ -16,7 +16,7 @@ int main(int argc, char **argv) { if (argc == 2 || (argc == 3 && String(argv[2]) == "debug")) { std::ifstream handler(String(argv[1]).data()); if (!handler.is_open()) - ErrHandler().CallErr("From Interpreter: cannot open the file"); + ErrHandler().CallErr(-1, "From Interpreter: cannot open the file"); String codeline; std::vector code; @@ -29,7 +29,7 @@ int main(int argc, char **argv) { // interpret std::unordered_map stor; - AST main(Main, {}, {}); + AST main(Main, {}, {}, 0); if (argc == 3 && String(argv[2]) == "debug") { std::clock_t end, start = clock(); diff --git a/src/parser/parse.cpp b/src/parser/parse.cpp index f977332..d9ba97b 100644 --- a/src/parser/parse.cpp +++ b/src/parser/parse.cpp @@ -22,8 +22,8 @@ std::vector> runes{ std::vector funcs {"in", "out", "tostring", "toint"}; -Expr ParseExpr(std::vector tokens) { - Expr head({0,0,0}, Variable("_", "", OPERATOR)); +Expr ParseExpr(std::vector tokens, int parsing_line) { + Expr head({0,0,0}, Variable("_", "", OPERATOR), parsing_line); if (tokens.size() >= 3 && std::find(funcs.begin(), funcs.end(), tokens[0]) != funcs.end() && tokens[1] == "(" && tokens[tokens.size()-1] == ")") { @@ -35,11 +35,11 @@ Expr ParseExpr(std::vector tokens) { else if (!level) isSuitable = 0; } if (isSuitable) { - head = Expr({0,0,1}, Variable("_", tokens[0], OPERATOR)); + head = Expr({0,0,1}, Variable("_", tokens[0], OPERATOR), parsing_line); std::vector parameter; for (int idx = 2; idx < tokens.size()-1; idx++) { if (tokens[idx] == ",") { - if (parameter.size() == 0) ErrHandler().CallErr("Blank parameter"); + if (parameter.size() == 0) ErrHandler().CallErr(parsing_line, "Blank parameter"); head.AddChild(ParseExpr(parameter)); parameter.clear(); continue; @@ -64,16 +64,16 @@ Expr ParseExpr(std::vector tokens) { tokens = std::vector(tokens.begin()+1, tokens.end()-1); } - if (tokens.size() == 0) ErrHandler().CallErr("No operand"); + if (tokens.size() == 0) ErrHandler().CallErr(parsing_line, "No operand"); if (tokens.size() == 1) { if (std::regex_match(tokens[0], std::regex("[0-9]+"))) { - head = Expr({1, 0, 0}, Variable("_", tokens[0], INT)); + head = Expr({1, 0, 0}, Variable("_", tokens[0], INT), parsing_line); } else if (std::regex_match(tokens[0], std::regex("[0-9]+.[0-9]+"))) { - head = Expr({1, 0, 0}, Variable("_", tokens[0], DOUBLE)); + head = Expr({1, 0, 0}, Variable("_", tokens[0], DOUBLE), parsing_line); } else if (tokens[0][0] == '\"' && tokens[0][tokens[0].length()-1] == '\"') { - head = Expr({1, 0, 0}, Variable("_", tokens[0], STRING)); + head = Expr({1, 0, 0}, Variable("_", tokens[0], STRING), parsing_line); } else { - head = Expr({0, 1, 0}, Variable("_", tokens[0], OPERATOR)); + head = Expr({0, 1, 0}, Variable("_", tokens[0], OPERATOR), parsing_line); } return head; } @@ -86,15 +86,15 @@ Expr ParseExpr(std::vector tokens) { else if (token == ")") level--; else if (!level) isTarget[idx] = 1; } - if (level != 0) ErrHandler().CallErr("Unmatched parenthesis"); + if (level != 0) ErrHandler().CallErr(parsing_line, "Unmatched parenthesis"); // priority 1 for (int idx = 0; idx < tokens.size(); idx++) { if (!isTarget[idx]) continue; String token = tokens[idx]; if (token == "||") { - if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr("operator || cannot be unary"); - head = Expr({0, 0, 0}, Variable("_", "||", OPERATOR)); + if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator || cannot be unary"); + head = Expr({0, 0, 0}, Variable("_", "||", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -108,8 +108,8 @@ Expr ParseExpr(std::vector tokens) { if (!isTarget[idx]) continue; String token = tokens[idx]; if (token == "&&") { - if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr("operator && cannot be unary"); - head = Expr({0, 0, 0}, Variable("_", "&&", OPERATOR)); + if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator && cannot be unary"); + head = Expr({0, 0, 0}, Variable("_", "&&", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -123,8 +123,8 @@ Expr ParseExpr(std::vector tokens) { if (!isTarget[idx]) continue; String token = tokens[idx]; if (token == "==") { - if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr("operator == cannot be unary"); - head = Expr({0, 0, 0}, Variable("_", "==", OPERATOR)); + if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator == cannot be unary"); + head = Expr({0, 0, 0}, Variable("_", "==", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -132,8 +132,8 @@ Expr ParseExpr(std::vector tokens) { return head; } if (token == "!=") { - if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr("operator != cannot be unary"); - head = Expr({0, 0, 0}, Variable("_", "!=", OPERATOR)); + if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator != cannot be unary"); + head = Expr({0, 0, 0}, Variable("_", "!=", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -141,8 +141,8 @@ Expr ParseExpr(std::vector tokens) { return head; } if (token == "<") { - if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr("operator < cannot be unary"); - head = Expr({0, 0, 0}, Variable("_", "<", OPERATOR)); + if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator < cannot be unary"); + head = Expr({0, 0, 0}, Variable("_", "<", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -150,8 +150,8 @@ Expr ParseExpr(std::vector tokens) { return head; } if (token == "<=") { - if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr("operator <= cannot be unary"); - head = Expr({0, 0, 0}, Variable("_", "<=", OPERATOR)); + if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator <= cannot be unary"); + head = Expr({0, 0, 0}, Variable("_", "<=", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -159,8 +159,8 @@ Expr ParseExpr(std::vector tokens) { return head; } if (token == ">") { - if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr("operator > cannot be unary"); - head = Expr({0, 0, 0}, Variable("_", ">", OPERATOR)); + if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator > cannot be unary"); + head = Expr({0, 0, 0}, Variable("_", ">", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -168,8 +168,8 @@ Expr ParseExpr(std::vector tokens) { return head; } if (token == ">=") { - if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr("operator >= cannot be unary"); - head = Expr({0, 0, 0}, Variable("_", ">=", OPERATOR)); + if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator >= cannot be unary"); + head = Expr({0, 0, 0}, Variable("_", ">=", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -185,21 +185,21 @@ Expr ParseExpr(std::vector tokens) { if (token == "+") { if (idx != 0 && std::find(operators.begin(), operators.end(), tokens[idx - 1]) != operators.end()) continue; - if (idx == tokens.size()-1) ErrHandler().CallErr("operator + cannot be unary"); + if (idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator + cannot be unary"); if (idx == 0) { - if (tokens.size() != 2) ErrHandler().CallErr("invalid unary operation form"); + if (tokens.size() != 2) ErrHandler().CallErr(parsing_line, "invalid unary operation form"); if (std::regex_match(tokens[1], std::regex("[0-9]+"))) { - head = Expr({1, 0, 0}, Variable("_", tokens[1], INT)); + head = Expr({1, 0, 0}, Variable("_", tokens[1], INT), parsing_line); } else if (std::regex_match(tokens[1], std::regex("[0-9]+.[0-9]+"))) { - head = Expr({1, 0, 0}, Variable("_", tokens[1], DOUBLE)); + head = Expr({1, 0, 0}, Variable("_", tokens[1], DOUBLE), parsing_line); } else if (tokens[1][0] == '\"' && tokens[1][tokens[1].length()-1] == '\"') { - ErrHandler().CallErr("operator + in unary use cannot be used with string constant"); + ErrHandler().CallErr(parsing_line, "operator + in unary use cannot be used with string constant"); } else { - ErrHandler().CallErr("operator + in unary use cannot be used with lvalue"); + ErrHandler().CallErr(parsing_line, "operator + in unary use cannot be used with lvalue"); } return head; } - head = Expr({0, 0, 0}, Variable("_", "+", OPERATOR)); + head = Expr({0, 0, 0}, Variable("_", "+", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -207,23 +207,23 @@ Expr ParseExpr(std::vector tokens) { return head; } if (token == "-") { - if (idx == tokens.size()-1) ErrHandler().CallErr("operator - cannot be unary"); + if (idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator - cannot be unary"); if (std::find(operators.begin(), operators.end(), tokens[idx - 1]) != operators.end()) continue; if (idx == 0) { - if (tokens.size() != 2) ErrHandler().CallErr("invalid unary operation form"); + if (tokens.size() != 2) ErrHandler().CallErr(parsing_line, "invalid unary operation form"); if (std::regex_match(tokens[1], std::regex("[0-9]+"))) { - head = Expr({1, 0, 0}, Variable("_", "-" + tokens[1], INT)); + head = Expr({1, 0, 0}, Variable("_", "-" + tokens[1], INT), parsing_line); } else if (std::regex_match(tokens[1], std::regex("[0-9]+.[0-9]+"))) { - head = Expr({1, 0, 0}, Variable("_", "-" + tokens[1], DOUBLE)); + head = Expr({1, 0, 0}, Variable("_", "-" + tokens[1], DOUBLE), parsing_line); } else if (tokens[1][0] == '\"' && tokens[1][tokens[1].length()-1] == '\"') { - ErrHandler().CallErr("operator - in unary use cannot be used with string constant"); + ErrHandler().CallErr(parsing_line, "operator - in unary use cannot be used with string constant"); } else { - ErrHandler().CallErr("operator - in unary use cannot be used with lvalue"); + ErrHandler().CallErr(parsing_line, "operator - in unary use cannot be used with lvalue"); } return head; } - head = Expr({0, 0, 0}, Variable("_", "-", OPERATOR)); + head = Expr({0, 0, 0}, Variable("_", "-", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -237,8 +237,8 @@ Expr ParseExpr(std::vector tokens) { String token = tokens[idx]; if (!isTarget[idx]) continue; if (token == "*") { - if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr("operator * cannot be unary"); - head = Expr({0, 0, 0}, Variable("_", "*", OPERATOR)); + if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator * cannot be unary"); + head = Expr({0, 0, 0}, Variable("_", "*", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -246,8 +246,8 @@ Expr ParseExpr(std::vector tokens) { return head; } if (token == "/") { - if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr("operator / cannot be unary"); - head = Expr({0, 0, 0}, Variable("_", "/", OPERATOR)); + if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator / cannot be unary"); + head = Expr({0, 0, 0}, Variable("_", "/", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -255,8 +255,8 @@ Expr ParseExpr(std::vector tokens) { return head; } if (token == "%") { - if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr("operator % cannot be unary"); - head = Expr({0, 0, 0}, Variable("_", "%", OPERATOR)); + if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator % cannot be unary"); + head = Expr({0, 0, 0}, Variable("_", "%", OPERATOR), parsing_line); head.SetChildren({ ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) @@ -270,8 +270,8 @@ Expr ParseExpr(std::vector tokens) { String token = tokens[idx]; if (!isTarget[idx]) continue; if (token == "!") { - if (idx == tokens.size()-1) ErrHandler().CallErr("operator ! cannot appear after identifier"); - head = Expr({0, 0, 0}, Variable("_", "!", OPERATOR)); + if (idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator ! cannot appear after identifier"); + head = Expr({0, 0, 0}, Variable("_", "!", OPERATOR), parsing_line); head.SetChildren({ ParseExpr({tokens[idx+1]}) }); @@ -279,10 +279,11 @@ Expr ParseExpr(std::vector tokens) { } } - ErrHandler().CallErr("invalid expression."); + ErrHandler().CallErr(parsing_line, "invalid expression."); } void Parse(AST& head, std::vector codes) { + int parsing_line = head.codeline; std::vector> tokenss(codes.size()); for (int idx = 0; idx < codes.size(); idx++) { String code = codes[idx]; @@ -391,11 +392,11 @@ void Parse(AST& head, std::vector codes) { if (tokens.size() == 0) break; if (tokens.size() >= 1 && tokens[0] == "//") break; if (tokens.size() == 1 && tokens[0] == "break") { - AST ast(BreakStmt, {}, {}); head.AddChild(ast); + AST ast(BreakStmt, {}, {}, parsing_line); head.AddChild(ast); break; } if (tokens.size() == 1 && tokens[0] == "continue") { - AST ast(ContinueStmt, {}, {}); head.AddChild(ast); + AST ast(ContinueStmt, {}, {}, parsing_line); head.AddChild(ast); break; } if (tokens.size() == 1 && tokens[0] == "}") { @@ -404,12 +405,12 @@ void Parse(AST& head, std::vector codes) { if (tokens[0] == "if") { if (tokens.size() < 4 || tokens[1] != "(" || tokens[tokens.size()-2] != ")" || tokens[tokens.size()-1] != "{") - ErrHandler().CallErr("No matching syntax: if"); + ErrHandler().CallErr(parsing_line, "No matching syntax: if"); AST ast(IfStmt, {}, { ParseExpr(std::vector(tokens.begin()+2, tokens.end()-2)) - } + }, parsing_line ); int level = 0, iidx; @@ -428,12 +429,12 @@ void Parse(AST& head, std::vector codes) { if (tokens[0] == "elif") { if (tokens.size() < 4 || tokens[1] != "(" || tokens[tokens.size()-2] != ")" || tokens[tokens.size()-1] != "{") - ErrHandler().CallErr("No matching syntax: elif"); + ErrHandler().CallErr(parsing_line, "No matching syntax: elif"); AST ast(ElifStmt, {}, { ParseExpr(std::vector(tokens.begin()+2, tokens.end()-2)) - } + }, parsing_line ); int level = 0, iidx; @@ -451,9 +452,9 @@ void Parse(AST& head, std::vector codes) { } if (tokens[0] == "else") { if (tokens.size() != 2 || tokens[1] != "{") - ErrHandler().CallErr("No matching syntax: else"); + ErrHandler().CallErr(parsing_line, "No matching syntax: else"); - AST ast(ElseStmt, {}, {}); + AST ast(ElseStmt, {}, {}, parsing_line); int level = 0, iidx; for (iidx = idx; iidx < tokenss.size(); iidx++) { @@ -470,7 +471,7 @@ void Parse(AST& head, std::vector codes) { } if (tokens[0] == "for") { if (tokens.size() < 4) - ErrHandler().CallErr("No matching syntax: for"); + ErrHandler().CallErr(parsing_line, "No matching syntax: for"); if (std::find(tokens.begin(), tokens.end(), "range") != tokens.end()) { // for clause if (tokens[2] != "in" || @@ -479,18 +480,18 @@ void Parse(AST& head, std::vector codes) { tokens[tokens.size()-1] != "{" || tokens[tokens.size()-2] != ")" ) - ErrHandler().CallErr("No matching syntax: for"); + ErrHandler().CallErr(parsing_line, "No matching syntax: for"); AST ast(ForClauseStmt, { Variable("_", tokens[1], OPERATOR), - }, {}); + }, {}, parsing_line); std::vector caches; int grammar_checknum = 0; for (int iidx = 5; iidx < tokens.size()-2; iidx++) { if (tokens[iidx] == ",") { if (grammar_checknum > 3) - ErrHandler().CallErr("For clause only has three elements: start, end, step"); + ErrHandler().CallErr(parsing_line, "For clause only has three elements: start, end, step"); grammar_checknum++; ast.AddExpr(ParseExpr(caches)); @@ -500,14 +501,14 @@ void Parse(AST& head, std::vector codes) { caches.push_back(tokens[iidx]); } if (!caches.size()) { - ErrHandler().CallErr("For clause doesn't allow blank expression"); + ErrHandler().CallErr(parsing_line, "For clause doesn't allow blank expression"); } ast.AddExpr(ParseExpr(caches)); caches.clear(); grammar_checknum++; if (grammar_checknum != 3) - ErrHandler().CallErr("For clause only has three elements: start, end, step"); + ErrHandler().CallErr(parsing_line, "For clause only has three elements: start, end, step"); int level = 0, iidx; for (iidx = idx; iidx < tokenss.size(); iidx++) { @@ -526,12 +527,12 @@ void Parse(AST& head, std::vector codes) { // ForSCStmt if (tokens.size() < 4 || tokens[1] != "(" || tokens[tokens.size()-2] != ")" || tokens[tokens.size()-1] != "{") - ErrHandler().CallErr("No matching syntax: for"); + ErrHandler().CallErr(parsing_line, "No matching syntax: for"); AST ast(ForSCStmt, {}, { ParseExpr(std::vector(tokens.begin()+2, tokens.end()-2)) - } + }, parsing_line ); int level = 0, iidx; @@ -551,7 +552,7 @@ void Parse(AST& head, std::vector codes) { AST ast(Expression, {}, { ParseExpr(tokens) - } + }, parsing_line ); head.AddChild(ast); break; @@ -563,21 +564,21 @@ void Parse(AST& head, std::vector codes) { if (pos == 1) { // assignment if (tokens.size() < 3) - ErrHandler().CallErr("No matching syntax: assignment"); + ErrHandler().CallErr(parsing_line, "No matching syntax: assignment"); AST ast(Assignment, { Variable("_", tokens[0], OPERATOR) }, { ParseExpr(std::vector(tokens.begin()+2, tokens.end())) - } + }, parsing_line ); head.AddChild(ast); break; } if (pos == 2) { // VarDel if (tokens.size() < 4) - ErrHandler().CallErr("No matching syntax: declaration"); + ErrHandler().CallErr(parsing_line, "No matching syntax: declaration"); AST ast(VarDel, { @@ -585,14 +586,14 @@ void Parse(AST& head, std::vector codes) { Variable("_", tokens[1], OPERATOR) }, { ParseExpr(std::vector(tokens.begin()+3, tokens.end())) - } + }, parsing_line ); head.AddChild(ast); break; } if (pos == 3) { // ConstDel if (tokens.size() < 5) - ErrHandler().CallErr("No matching syntax: declaration"); + ErrHandler().CallErr(parsing_line, "No matching syntax: declaration"); AST ast(ConstDel, { @@ -600,18 +601,18 @@ void Parse(AST& head, std::vector codes) { Variable("_", tokens[2], OPERATOR) }, { ParseExpr(std::vector(tokens.begin()+4, tokens.end())) - } + }, parsing_line ); head.AddChild(ast); break; } - ErrHandler().CallErr("Unknown syntax"); + ErrHandler().CallErr(parsing_line, "Unknown syntax"); break; } default: // error - ErrHandler().CallErr("Unknown syntax"); + ErrHandler().CallErr(parsing_line, "Unknown syntax"); break; } } diff --git a/src/runtime/AST.h b/src/runtime/AST.h index 854882c..05488a6 100644 --- a/src/runtime/AST.h +++ b/src/runtime/AST.h @@ -44,17 +44,20 @@ enum StmtType { * - bool constant, variable, call (token's type) * - Variable token * - std::vector children + * - int codeline */ + class Expr { private: bool constant = 0, variable = 0, call = 0; Variable token; std::vector children; + int codeline; public: // constructor - Expr(std::vector t, Variable tkn) { - token = tkn, constant = t[0], variable = t[1], call = t[2]; + Expr(std::vector t, Variable tkn, int _codeline) { + token = tkn, constant = t[0], variable = t[1], call = t[2], codeline = _codeline; } void SetChildren(std::vector rplcment) { @@ -72,7 +75,7 @@ class Expr { if (variable) { auto iter = storage.find(tkn); if (iter == storage.end()) // has variable declared? - ErrHandler().CallErr(tkn + " has not declared yet"); + ErrHandler().CallErr(codeline, tkn + " has not declared yet"); return iter->second; } if (constant) { @@ -85,7 +88,7 @@ class Expr { } ArrayWithCode res = EExecFunc(tkn, arg); if (res.error == ERROR) - ErrHandler().CallErr("Error occured while calling " + tkn); + ErrHandler().CallErr(codeline, "Error occured while calling " + tkn); return res.var.container[0]; } @@ -151,6 +154,8 @@ typedef std::unordered_map Storage; * - std::vector childStmt * - std::vector expression * - std::vector argument + * public + * - int codeline * * expression * @@ -185,9 +190,11 @@ class AST { std::vector argument; public: + int codeline; + // constructor - AST(StmtType t, std::vector argv, std::vector expr) { - _t = t, argument = argv, expression = expr; + AST(StmtType t, std::vector argv, std::vector expr, int _codeline) { + _t = t, argument = argv, expression = expr, codeline = _codeline; } void SetChildren(std::vector rplcment) { @@ -226,7 +233,7 @@ class AST { std::pair res = ast.Execute(storage); if (res.first >= 1) - ErrHandler().CallErr("break and continue statement only allowed to be used in for statements"); + ErrHandler().CallErr(codeline, "break and continue statement only allowed to be used in for statements"); if (res.second) { ignoreif = 1; @@ -239,7 +246,7 @@ class AST { case ConstDel: { Variable v_type = argument[0], v_identifier = argument[1]; if (storage.find(v_identifier.GetValue()) != storage.end()) - ErrHandler().CallErr("Redefine variable " + v_identifier.GetValue()); + ErrHandler().CallErr(codeline, "Redefine variable " + v_identifier.GetValue()); TYPE v_t = v_type.GetValue() == "int" ? INT : ( v_type.GetValue() == "bool" ? BOOL : ( @@ -262,7 +269,7 @@ class AST { case VarDel: { Variable v_type = argument[0], v_identifier = argument[1]; if (storage.find(v_identifier.GetValue()) != storage.end()) - ErrHandler().CallErr("Redefine variable " + v_identifier.GetValue()); + ErrHandler().CallErr(codeline, "Redefine variable " + v_identifier.GetValue()); TYPE v_t = v_type.GetValue() == "int" ? INT : ( v_type.GetValue() == "bool" ? BOOL : ( @@ -288,10 +295,10 @@ class AST { case Assignment: { Variable v_identifier = argument[0]; if (storage.find(v_identifier.GetValue()) == storage.end()) - ErrHandler().CallErr("Variable " + v_identifier.GetValue() + " hasn't defined yet"); + ErrHandler().CallErr(codeline, "Variable " + v_identifier.GetValue() + " hasn't defined yet"); if (storage[v_identifier.GetValue()].constant) - ErrHandler().CallErr(v_identifier.GetValue() + " is constant"); + ErrHandler().CallErr(codeline, v_identifier.GetValue() + " is constant"); storage[v_identifier.GetValue()].Substitute(expression[0].Execute(storage).GetValue()); break; @@ -307,7 +314,7 @@ class AST { Storage local = storage; Variable condition = expression[0].Execute(local); if (condition._t != BOOL) - ErrHandler().CallErr("If Statement allows only boolean condition expression."); + ErrHandler().CallErr(codeline, "If Statement allows only boolean condition expression."); if (condition.GetValue() == "0") { return {0, false}; } @@ -320,7 +327,7 @@ class AST { std::pair res = ast.Execute(local); if (res.first >= 1) { return {res.first, res.second}; - ErrHandler().CallErr("If Statement doesn't allow to use break or continue statement."); + ErrHandler().CallErr(codeline, "If Statement doesn't allow to use break or continue statement."); } if (res.second) { ignoreif = 1; @@ -340,7 +347,7 @@ class AST { Storage local = storage; Variable condition = expression[0].Execute(local); if (condition._t != BOOL) - ErrHandler().CallErr("Elif Statement allows only boolean condition expression."); + ErrHandler().CallErr(codeline, "Elif Statement allows only boolean condition expression."); if (condition.GetValue() == "0") { return {0, false}; } @@ -353,7 +360,7 @@ class AST { std::pair res = ast.Execute(local); if (res.first >= 1) { return {res.first, res.second}; - ErrHandler().CallErr("Elif Statement doesn't allow to use break or continue statement."); + ErrHandler().CallErr(codeline, "Elif Statement doesn't allow to use break or continue statement."); } if (res.second) { ignoreif = 1; @@ -380,7 +387,7 @@ class AST { std::pair res = ast.Execute(local); if (res.first >= 1) { return {res.first, res.second}; - ErrHandler().CallErr("Else Statement doesn't allow to use break or continue statement."); + ErrHandler().CallErr(codeline, "Else Statement doesn't allow to use break or continue statement."); } if (res.second) { ignoreif = 1; @@ -434,7 +441,7 @@ class AST { while (1) { Variable condition = expression[0].Execute(local); if (condition._t != BOOL) - ErrHandler().CallErr("For Statement allows only boolean condition expression."); + ErrHandler().CallErr(codeline, "For Statement allows only boolean condition expression."); if (condition.GetValue() == "0") break; bool ignoreif = 0; diff --git a/src/type/variable.h b/src/type/variable.h index f311c37..dbe5fd1 100644 --- a/src/type/variable.h +++ b/src/type/variable.h @@ -42,41 +42,43 @@ class Variable { std::string value; std::string token; bool constant = 0; + int runtime_codeline; // for error analyzing TYPE _t; // constructor - Variable(std::string varname = "_", std::string val = "", TYPE t = OPERATOR, bool con = 0) { - if (varname == "") ErrHandler().CallErr("Name of variable should not be blank. How about using '_'?"); - + Variable(std::string varname = "_", std::string val = "", TYPE t = OPERATOR, int _runtime_codeline = -1, bool con = 0) { + runtime_codeline = _runtime_codeline; _t = t; token = varname; constant = con; - if (Substitute(val) == ERROR) ErrHandler().CallErr("Type of value does not match with declaration"); + + if (varname == "") ErrHandler().CallErr(runtime_codeline, "Name of variable should not be blank. How about using '_'?"); + if (Substitute(val) == ERROR) ErrHandler().CallErr(runtime_codeline, "Type of value does not match with declaration"); } // operation Variable operator + (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", _t); switch (_t) { case BOOL: case INT: - if (operand._t == STRING) ErrHandler().CallErr("No matching operation between int and string was found."); + if (operand._t == STRING) ErrHandler().CallErr(runtime_codeline, "No matching operation between int and string was found."); if (operand._t == DOUBLE) res.Substitute(std::to_string((Int)(std::stoi(value)+std::stod(operand.value)))); else res.Substitute(std::to_string(std::stoi(value)+std::stoi(operand.value))); break; case DOUBLE: - if (operand._t == STRING) ErrHandler().CallErr("No matching operation between double and string was found."); + if (operand._t == STRING) ErrHandler().CallErr(runtime_codeline, "No matching operation between double and string was found."); if (operand._t == DOUBLE) res.Substitute(std::to_string(std::stod(value)+std::stod(operand.value))); else res.Substitute(std::to_string(std::stod(value)+std::stoi(operand.value))); break; case STRING: - if (operand._t != STRING) ErrHandler().CallErr("The only string can operate with string."); + if (operand._t != STRING) ErrHandler().CallErr(runtime_codeline, "The only string can operate with string."); res.Substitute("\""+trim(value)+trim(operand.value)+"\""); break; } @@ -84,10 +86,10 @@ class Variable { } Variable operator - (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", _t); - if (operand._t == STRING || _t == STRING) ErrHandler().CallErr("No matching operation with string and any was found."); + if (operand._t == STRING || _t == STRING) ErrHandler().CallErr(runtime_codeline, "No matching operation with string and any was found."); switch (_t) { case BOOL: case INT: @@ -107,10 +109,10 @@ class Variable { } Variable operator * (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", _t); - if (operand._t == STRING || _t == STRING) ErrHandler().CallErr("No matching operation with string and any was found."); + if (operand._t == STRING || _t == STRING) ErrHandler().CallErr(runtime_codeline, "No matching operation with string and any was found."); switch (_t) { case BOOL: case INT: @@ -130,11 +132,11 @@ class Variable { } Variable operator / (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", _t); - if (operand._t == STRING || _t == STRING) ErrHandler().CallErr("No matching operation with string and any was found."); - if (operand.GetValue() == "0") ErrHandler().CallErr("Not allowed to divide with zero"); + if (operand._t == STRING || _t == STRING) ErrHandler().CallErr(runtime_codeline, "No matching operation with string and any was found."); + if (operand.GetValue() == "0") ErrHandler().CallErr(runtime_codeline, "Not allowed to divide with zero"); switch (_t) { case BOOL: case INT: @@ -154,11 +156,11 @@ class Variable { } Variable operator % (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", _t); - if (operand._t == STRING || _t == STRING) ErrHandler().CallErr("No matching operation with string and any was found."); - if (operand.GetValue() == "0") ErrHandler().CallErr("Not allowed to divide with zero"); + if (operand._t == STRING || _t == STRING) ErrHandler().CallErr(runtime_codeline, "No matching operation with string and any was found."); + if (operand.GetValue() == "0") ErrHandler().CallErr(runtime_codeline, "Not allowed to divide with zero"); switch (_t) { case INT: res.Substitute(std::to_string(std::stoi(value)%std::stoi(operand.value))); @@ -168,76 +170,76 @@ class Variable { } Variable operator == (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", BOOL); - if (operand._t != _t) ErrHandler().CallErr("Not allowed to compare between different type variables."); + if (operand._t != _t) ErrHandler().CallErr(runtime_codeline, "Not allowed to compare between different type variables."); res.Substitute(std::to_string(operand.GetValue()==GetValue())); return res; } Variable operator != (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", BOOL); - if (operand._t != _t) ErrHandler().CallErr("Not allowed to compare between different type variables."); + if (operand._t != _t) ErrHandler().CallErr(runtime_codeline, "Not allowed to compare between different type variables."); res.Substitute(std::to_string(operand.GetValue()!=GetValue())); return res; } Variable operator > (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", BOOL); try { res.Substitute(std::to_string(operand.GetValue()>GetValue())); } catch(const std::exception& e) { - ErrHandler().CallErr("Something went wrong :("); + ErrHandler().CallErr(runtime_codeline, "Something went wrong :("); } return res; } Variable operator < (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", BOOL); try { res.Substitute(std::to_string(operand.GetValue()= (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", BOOL); try { res.Substitute(std::to_string(operand.GetValue()>=GetValue())); } catch(const std::exception& e) { - ErrHandler().CallErr("Something went wrong :("); + ErrHandler().CallErr(runtime_codeline, "Something went wrong :("); } return res; } Variable operator <= (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", BOOL); try { res.Substitute(std::to_string(operand.GetValue()<=GetValue())); } catch(const std::exception& e) { - ErrHandler().CallErr("Something went wrong :("); + ErrHandler().CallErr(runtime_codeline, "Something went wrong :("); } return res; @@ -246,7 +248,7 @@ class Variable { Variable operator ! () { Variable res = Variable("_", "", BOOL); - if (_t != BOOL) ErrHandler().CallErr("Operation ! allows only boolean variables."); + if (_t != BOOL) ErrHandler().CallErr(runtime_codeline, "Operation ! allows only boolean variables."); res.Substitute(std::to_string( !(std::stoi(GetValue())) )); @@ -254,9 +256,9 @@ class Variable { } Variable operator && (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", BOOL); - if (_t != BOOL || operand._t != BOOL) ErrHandler().CallErr("Operation && allows only boolean variables."); + if (_t != BOOL || operand._t != BOOL) ErrHandler().CallErr(runtime_codeline, "Operation && allows only boolean variables."); res.Substitute(std::to_string(std::stoi(operand.GetValue())&&std::stoi(GetValue()))); @@ -264,9 +266,9 @@ class Variable { } Variable operator || (Variable operand) { - if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr("Operand should not be blank."); + if (operand.GetValue() == "" || GetValue() == "") ErrHandler().CallErr(runtime_codeline, "Operand should not be blank."); Variable res = Variable("_", "", BOOL); - if (_t != BOOL || operand._t != BOOL) ErrHandler().CallErr("Operation || allows only boolean variables."); + if (_t != BOOL || operand._t != BOOL) ErrHandler().CallErr(runtime_codeline, "Operation || allows only boolean variables."); res.Substitute(std::to_string(std::stoi(operand.GetValue())||std::stoi(GetValue()))); From dd03268f9895d53632cfecd086757dc11c8fb7ca Mon Sep 17 00:00:00 2001 From: RedoC-github Date: Tue, 25 Jan 2022 20:06:43 +0900 Subject: [PATCH 2/6] add the base of new error handling --- sample/hello_wopslang.wops | 2 +- src/parser/parse.cpp | 76 +++++++++++++++++++------------------- src/parser/parse.h | 2 +- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/sample/hello_wopslang.wops b/sample/hello_wopslang.wops index f32ebc1..b99519d 100644 --- a/sample/hello_wopslang.wops +++ b/sample/hello_wopslang.wops @@ -5,5 +5,5 @@ // 2021, Wops Team // -out("Hello, Wopslang!") +out("Hello, Wopslang!" out("안녕, 옵스랭!") diff --git a/src/parser/parse.cpp b/src/parser/parse.cpp index d9ba97b..d276639 100644 --- a/src/parser/parse.cpp +++ b/src/parser/parse.cpp @@ -40,14 +40,14 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { for (int idx = 2; idx < tokens.size()-1; idx++) { if (tokens[idx] == ",") { if (parameter.size() == 0) ErrHandler().CallErr(parsing_line, "Blank parameter"); - head.AddChild(ParseExpr(parameter)); + head.AddChild(ParseExpr(parameter, parsing_line)); parameter.clear(); continue; } parameter.push_back(tokens[idx]); } if (parameter.size() != 0) - head.AddChild(ParseExpr(parameter)); + head.AddChild(ParseExpr(parameter, parsing_line)); return head; } } @@ -96,8 +96,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator || cannot be unary"); head = Expr({0, 0, 0}, Variable("_", "||", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -111,8 +111,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator && cannot be unary"); head = Expr({0, 0, 0}, Variable("_", "&&", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -126,8 +126,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator == cannot be unary"); head = Expr({0, 0, 0}, Variable("_", "==", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -135,8 +135,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator != cannot be unary"); head = Expr({0, 0, 0}, Variable("_", "!=", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -144,8 +144,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator < cannot be unary"); head = Expr({0, 0, 0}, Variable("_", "<", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -153,8 +153,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator <= cannot be unary"); head = Expr({0, 0, 0}, Variable("_", "<=", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -162,8 +162,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator > cannot be unary"); head = Expr({0, 0, 0}, Variable("_", ">", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -171,8 +171,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator >= cannot be unary"); head = Expr({0, 0, 0}, Variable("_", ">=", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -201,8 +201,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { } head = Expr({0, 0, 0}, Variable("_", "+", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -225,8 +225,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { } head = Expr({0, 0, 0}, Variable("_", "-", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -240,8 +240,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator * cannot be unary"); head = Expr({0, 0, 0}, Variable("_", "*", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -249,8 +249,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator / cannot be unary"); head = Expr({0, 0, 0}, Variable("_", "/", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -258,8 +258,8 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { if (idx == 0 || idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator % cannot be unary"); head = Expr({0, 0, 0}, Variable("_", "%", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx)), - ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end())) + ParseExpr(std::vector(tokens.begin(), tokens.begin()+idx), parsing_line), + ParseExpr(std::vector(tokens.begin()+idx+1, tokens.end()), parsing_line) }); return head; } @@ -273,7 +273,7 @@ Expr ParseExpr(std::vector tokens, int parsing_line) { if (idx == tokens.size()-1) ErrHandler().CallErr(parsing_line, "operator ! cannot appear after identifier"); head = Expr({0, 0, 0}, Variable("_", "!", OPERATOR), parsing_line); head.SetChildren({ - ParseExpr({tokens[idx+1]}) + ParseExpr({tokens[idx+1]}, parsing_line) }); return head; } @@ -409,7 +409,7 @@ void Parse(AST& head, std::vector codes) { AST ast(IfStmt, {}, { - ParseExpr(std::vector(tokens.begin()+2, tokens.end()-2)) + ParseExpr(std::vector(tokens.begin()+2, tokens.end()-2), parsing_line) }, parsing_line ); @@ -433,7 +433,7 @@ void Parse(AST& head, std::vector codes) { AST ast(ElifStmt, {}, { - ParseExpr(std::vector(tokens.begin()+2, tokens.end()-2)) + ParseExpr(std::vector(tokens.begin()+2, tokens.end()-2), parsing_line) }, parsing_line ); @@ -494,7 +494,7 @@ void Parse(AST& head, std::vector codes) { ErrHandler().CallErr(parsing_line, "For clause only has three elements: start, end, step"); grammar_checknum++; - ast.AddExpr(ParseExpr(caches)); + ast.AddExpr(ParseExpr(caches, parsing_line)); caches.clear(); continue; } @@ -503,7 +503,7 @@ void Parse(AST& head, std::vector codes) { if (!caches.size()) { ErrHandler().CallErr(parsing_line, "For clause doesn't allow blank expression"); } - ast.AddExpr(ParseExpr(caches)); + ast.AddExpr(ParseExpr(caches, parsing_line)); caches.clear(); grammar_checknum++; @@ -531,7 +531,7 @@ void Parse(AST& head, std::vector codes) { AST ast(ForSCStmt, {}, { - ParseExpr(std::vector(tokens.begin()+2, tokens.end()-2)) + ParseExpr(std::vector(tokens.begin()+2, tokens.end()-2), parsing_line) }, parsing_line ); @@ -551,7 +551,7 @@ void Parse(AST& head, std::vector codes) { AST ast(Expression, {}, { - ParseExpr(tokens) + ParseExpr(tokens, parsing_line) }, parsing_line ); head.AddChild(ast); @@ -570,7 +570,7 @@ void Parse(AST& head, std::vector codes) { { Variable("_", tokens[0], OPERATOR) }, { - ParseExpr(std::vector(tokens.begin()+2, tokens.end())) + ParseExpr(std::vector(tokens.begin()+2, tokens.end()), parsing_line) }, parsing_line ); head.AddChild(ast); @@ -585,7 +585,7 @@ void Parse(AST& head, std::vector codes) { Variable("_", tokens[0], OPERATOR), Variable("_", tokens[1], OPERATOR) }, { - ParseExpr(std::vector(tokens.begin()+3, tokens.end())) + ParseExpr(std::vector(tokens.begin()+3, tokens.end()), parsing_line) }, parsing_line ); head.AddChild(ast); @@ -600,7 +600,7 @@ void Parse(AST& head, std::vector codes) { Variable("_", tokens[1], OPERATOR), Variable("_", tokens[2], OPERATOR) }, { - ParseExpr(std::vector(tokens.begin()+4, tokens.end())) + ParseExpr(std::vector(tokens.begin()+4, tokens.end()), parsing_line) }, parsing_line ); head.AddChild(ast); diff --git a/src/parser/parse.h b/src/parser/parse.h index 4c021c6..fa7e6e8 100644 --- a/src/parser/parse.h +++ b/src/parser/parse.h @@ -17,6 +17,6 @@ #define WOPS_PARSE_H void Parse(AST& head, std::vector codes); -Expr ParseExpr(std::vector tokens); +Expr ParseExpr(std::vector tokens, int parsing_line); #endif From 2a2e17b8790b2af8e81c58db699f079f7681efa3 Mon Sep 17 00:00:00 2001 From: RedoC-github Date: Tue, 25 Jan 2022 20:08:10 +0900 Subject: [PATCH 3/6] hotfix --- sample/hello_wopslang.wops | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample/hello_wopslang.wops b/sample/hello_wopslang.wops index b99519d..f32ebc1 100644 --- a/sample/hello_wopslang.wops +++ b/sample/hello_wopslang.wops @@ -5,5 +5,5 @@ // 2021, Wops Team // -out("Hello, Wopslang!" +out("Hello, Wopslang!") out("안녕, 옵스랭!") From c15d8e1caccd1c46c816dc40afcc77de2f544373 Mon Sep 17 00:00:00 2001 From: RedoC-github Date: Tue, 25 Jan 2022 20:53:53 +0900 Subject: [PATCH 4/6] add new error handler system --- src/parser/parse.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/parser/parse.cpp b/src/parser/parse.cpp index d276639..1d2a332 100644 --- a/src/parser/parse.cpp +++ b/src/parser/parse.cpp @@ -386,6 +386,7 @@ void Parse(AST& head, std::vector codes) { } for (int idx = 0; idx < tokenss.size(); idx++) { + parsing_line++; std::vector tokens = tokenss[idx]; switch (std::count(tokens.begin(), tokens.end(), "=")) { case 0: { // expression, break, continue, if, for stmt @@ -423,6 +424,7 @@ void Parse(AST& head, std::vector codes) { } Parse(ast, std::vector(codes.begin()+idx+1, codes.begin()+iidx)); head.AddChild(ast); + parsing_line += iidx - idx; idx = iidx; break; } @@ -447,6 +449,7 @@ void Parse(AST& head, std::vector codes) { } Parse(ast, std::vector(codes.begin()+idx+1, codes.begin()+iidx)); head.AddChild(ast); + parsing_line += iidx - idx; idx = iidx; break; } @@ -466,6 +469,7 @@ void Parse(AST& head, std::vector codes) { } Parse(ast, std::vector(codes.begin()+idx+1, codes.begin()+iidx)); head.AddChild(ast); + parsing_line += iidx - idx; idx = iidx; break; } @@ -520,6 +524,7 @@ void Parse(AST& head, std::vector codes) { } Parse(ast, std::vector(codes.begin()+idx+1, codes.begin()+iidx)); head.AddChild(ast); + parsing_line += iidx - idx; idx = iidx; break; } @@ -545,6 +550,7 @@ void Parse(AST& head, std::vector codes) { } Parse(ast, std::vector(codes.begin()+idx+1, codes.begin()+iidx)); head.AddChild(ast); + parsing_line += iidx - idx; idx = iidx; break; } From bf8adbfa35fa47fd00b71e8505f3d098e119cb34 Mon Sep 17 00:00:00 2001 From: RedoC-github Date: Tue, 25 Jan 2022 22:12:59 +0900 Subject: [PATCH 5/6] v0.1.4 --- CHANGELOG | 9 ++++++++- README.md | 4 ++-- build.sh | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3fee3b7..e2f2cd1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,13 @@ - add more function - support Array(based on `std::vector`) +=== v0.1.4: === +- improvement + - fixed critical reported bug(#44, #43, #37) + - updated error handler (Now provide the line where the error occured!) + - now Windows user can use the latest Wopslang + - fixed some minor bugs + === v0.1.3: 88ad93d === - WARNING: THIS VERSION IS ONLY AVAILABLE FOR UNIX-TYPE OS. ALSO, WE STRONGLY RECOMMEND YOU TO UPDATE TO THIS VERSION. @@ -36,4 +43,4 @@ - if, for available -2021, Wops Team +2022, Wops Team diff --git a/README.md b/README.md index e6d0c71..66d23e8 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ func Wopslang(contributors) { ## Infomation -Version: **Wopslang v0.1.3 alpha** +Version: **Wopslang v0.1.4 alpha** License: Apache License 2.0 [⚒️ Official Documentation](./doc/README.md) [➕ VSCode Extension](https://github.com/Wopslang/vscode-wops) @@ -68,4 +68,4 @@ Special Thanks to @jhhan128 ![Wopslang Logo](https://emoji.slack-edge.com/T01MFM2TJ07/wopsfull/7fe35e7cbecd2d4d.png) -2021, Wops Team +2022, Wops Team diff --git a/build.sh b/build.sh index a5c9861..cfabf9e 100644 --- a/build.sh +++ b/build.sh @@ -6,7 +6,7 @@ echo -e "\033[92m██║███╗██║██║ ██║██╔═ echo -e "\033[92m╚███╔███╔╝╚██████╔╝██║ ███████║███████╗██║ ██║██║ ╚████║╚██████╔╝\033[m" echo -e "\033[92m ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ \033[m" echo -e "\n" -echo -e "✨ \033[1mWopslang v0.1.3 alpha Builder\033[m" +echo -e "✨ \033[1mWopslang v0.1.4 alpha Builder\033[m" echo -e "\033[91mWarning: This is alpha version. Some critical issues might be appeared.\033[m" echo -e -n "- make install..." make clean From b3b45990d7c4f51e70cf28726c1923afa296e1c6 Mon Sep 17 00:00:00 2001 From: RedoC-github Date: Tue, 25 Jan 2022 22:13:22 +0900 Subject: [PATCH 6/6] v0.1.4 --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index e2f2cd1..cc61250 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,7 +4,7 @@ - add more function - support Array(based on `std::vector`) -=== v0.1.4: === +=== v0.1.4: bf8adbf === - improvement - fixed critical reported bug(#44, #43, #37) - updated error handler (Now provide the line where the error occured!)