From 8aeae09e74b46ca52866f22b48f55fecdf27b849 Mon Sep 17 00:00:00 2001 From: Patrick Schönberger Date: Mon, 2 Aug 2021 14:43:11 +0200 Subject: type modifiers, parenthesized expressions, chained access expressions --- src/MyListener.h | 64 ------------ src/check.h | 49 ++++++++++ src/main.cpp | 10 +- src/repr.h | 4 + src/repr_get.h | 54 ++++++++-- src/toc.h | 293 ++++++++----------------------------------------------- 6 files changed, 139 insertions(+), 335 deletions(-) delete mode 100644 src/MyListener.h create mode 100644 src/check.h (limited to 'src') diff --git a/src/MyListener.h b/src/MyListener.h deleted file mode 100644 index 433fa7a..0000000 --- a/src/MyListener.h +++ /dev/null @@ -1,64 +0,0 @@ -#include "TocBaseListener.h" - -#include - -using namespace std; - -class MyListener : public TocBaseListener { - void enterVarDecl(TocParser::VarDeclContext * ctx) { - cout - << ctx->var()->type()->getText() - << " " - << ctx->var()->varName()->getText(); - - if (ctx->var()->expr() != nullptr) { - cout << " = "; - } - } - void exitVarDecl(TocParser::VarDeclContext * ctx) { - cout << ";" << endl; - } - - void enterFuncDecl(TocParser::FuncDeclContext * ctx) { - cout - << ctx->type()->getText() - << " " - << ctx->funcName()->getText() - << "("; - - if (ctx->parameter()->firstParameter() != nullptr) { - cout - << ctx->parameter()->firstParameter()->var()->type()->getText() - << " " - << ctx->parameter()->firstParameter()->var()->varName()->getText(); - } - - for (auto * p : ctx->parameter()->additionalParameter()) { - cout - << ", " - << p->var()->type()->getText() - << " " - << p->var()->varName()->getText(); - } - - cout - << ")"; - } - - void enterBody(TocParser::BodyContext * ctx) { - cout - << "{" << endl; - } - void exitBody(TocParser::BodyContext * ctx) { - cout - << "}" << endl; - } - - void enterIfCond(TocParser::IfCondContext * ctx) { - cout - << "if ("; - enterExpr(ctx->expr()); - cout - << ")"; - } -}; \ No newline at end of file diff --git a/src/check.h b/src/check.h new file mode 100644 index 0000000..9e6797f --- /dev/null +++ b/src/check.h @@ -0,0 +1,49 @@ +#pragma once + +#include "repr.h" + +bool checkStmt( + const Stmt & s, + std::vector structs, + std::vector funcs, + std::vector vars) +{ + // switch (s.type) { + // case StmtType::Assign: + // if (!checkVar(s._assign.)) + // } + return true; +} + +bool checkFunction( + const Function & f, + std::vector structs, + std::vector funcs, + std::vector vars) +{ + vars.insert(vars.end(), f.parameters.begin(), f.parameters.end()); + vars.insert(vars.end(), f.body.variables.begin(), f.body.variables.end()); + for (auto s : f.body.statements) { + if (!checkStmt(s, structs, funcs, vars)) + return false; + } + return true; +} + +bool checkProgram(const Program & p) +{ + for (auto f : p.functions) { + if (!checkFunction(f, p.structs, p.functions, p.variables)) + return false; + } + for (auto s : p.structs) { + std::vector vars = p.variables; + for (auto v : s.members) + vars.push_back(v); + for (auto f : s.methods) { + if (!checkFunction(f, p.structs, p.functions, vars)) + return false; + } + } + return true; +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 7d8d5c7..199f04d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ #include "toc.h" #include "repr.h" #include "repr_get.h" +#include "check.h" using namespace antlr4; @@ -33,15 +34,12 @@ int main(int argc, const char * argv[]) { //std::cout << "Parse Tree: " << s << std::endl; Program prg = getProgram(prog); - std::cout << "Variables:\n"; - for (auto v : prg.variables) - std::cout << " " << v.name << endl; - std::cout << "Functions:\n"; - for (auto f : prg.functions) - std::cout << " " << f.name << endl; tocProgram(std::cout, prg); + if (!checkProgram(prg)) + std::cerr << "Error" << std::endl; + //std::ofstream ofs("output.c"); //tocProg(ofs, prg); //ofs.close(); diff --git a/src/repr.h b/src/repr.h index cc28746..e45464c 100644 --- a/src/repr.h +++ b/src/repr.h @@ -22,6 +22,7 @@ struct UnaryOperatorExpr; struct BinaryOperatorExpr; struct TernaryOperatorExpr; struct DotExpr; +struct ParenExpr; struct Expr; struct IfStmt; struct SwitchStmt; @@ -38,6 +39,7 @@ enum class TypeModifierType { struct TypeModifier { TypeModifierType type; + bool _staticArray; int _arraySize; }; @@ -155,6 +157,8 @@ struct DotExpr { struct Expr { ExprType type; + bool parenthesized; + FuncExpr _func; LitExpr _lit; IdentifierExpr _identifier; diff --git a/src/repr_get.h b/src/repr_get.h index b624e4c..70ae3b1 100644 --- a/src/repr_get.h +++ b/src/repr_get.h @@ -22,9 +22,13 @@ Type getType(TocParser::TypeContext * ctx) { Type result; result.name = ctx->typeName()->NAME()->toString(); for (auto m : ctx->typeModifier()) { + bool isPointer = m->getText() == "*"; + bool isStaticArray = m->INT_LIT() != nullptr; + result.modifiers.emplace_back( - m->toString() == "*" ? TypeModifierType::Pointer : TypeModifierType::Array, - m->toString() == "*" ? -1 : atoi(m->NUMBER()->toString().c_str()) + isPointer ? TypeModifierType::Pointer : TypeModifierType::Array, + isStaticArray, + isStaticArray ? atoi(m->INT_LIT()->toString().c_str()) : -1 ); } return result; @@ -129,7 +133,6 @@ BinaryOperatorExpr getBinaryOperatorExpr(TocParser::OpExprContext * ctx) { result.rexpr = std::make_unique(getExpr(ctx->binaryOp()->nonOpExpr(1))); std::string op = ctx->binaryOp()->binary_op(0)->getText(); - std::cout << op << std::endl; result.type = getBinaryOperatorType(op); @@ -144,6 +147,7 @@ TernaryOperatorExpr getTernaryOperatorExpr(TocParser::OpExprContext * ctx) { } Expr getExpr(TocParser::NonOpExprContext * ctx) { Expr result; + result.parenthesized = false; if (ctx->funcExpr() != nullptr) { result.type = ExprType::Func; result._func.functionName = ctx->funcExpr()->funcName()->NAME()->toString(); @@ -175,17 +179,31 @@ Expr getExpr(TocParser::NonOpExprContext * ctx) { } if (ctx->parenExpr() != nullptr) { result = getExpr(ctx->parenExpr()->expr()); + result.parenthesized = true; } if (ctx->accessExpr() != nullptr) { - // TODO: access chain - for (auto sub : ctx->accessExpr()->accessSubExpr()) { + auto firstSub = ctx->accessExpr()->accessSubExpr(0); + if (firstSub->accessMember() != nullptr) { + result.type = ExprType::Dot; + result._dot.expr = std::make_unique(getExpr(ctx->accessExpr()->nonAccessExpr())); + result._dot.ident.name = firstSub->accessMember()->identifierExpr()->varName()->NAME()->toString(); + } + else { + result.type = ExprType::Brackets; + result._brackets.lexpr = std::make_unique(getExpr(ctx->accessExpr()->nonAccessExpr())); + result._brackets.rexpr = std::make_unique(getExpr(firstSub->accessBrackets()->expr())); + } + for (int i = 1; i < ctx->accessExpr()->accessSubExpr().size(); i++) { + Expr tmp = result; + auto sub = ctx->accessExpr()->accessSubExpr(i); if (sub->accessMember() != nullptr) { result.type = ExprType::Dot; + result._dot.expr = std::make_unique(tmp); result._dot.ident.name = sub->accessMember()->identifierExpr()->varName()->NAME()->toString(); } else { result.type = ExprType::Brackets; - result._brackets.lexpr = std::make_unique(getExpr(ctx->accessExpr()->nonAccessExpr())); + result._brackets.lexpr = std::make_unique(tmp); result._brackets.rexpr = std::make_unique(getExpr(sub->accessBrackets()->expr())); } } @@ -194,6 +212,7 @@ Expr getExpr(TocParser::NonOpExprContext * ctx) { } Expr getExpr(TocParser::NonAccessExprContext * ctx) { Expr result; + result.parenthesized = false; if (ctx->funcExpr() != nullptr) { result.type = ExprType::Func; result._func.functionName = ctx->funcExpr()->funcName()->NAME()->toString(); @@ -206,11 +225,13 @@ Expr getExpr(TocParser::NonAccessExprContext * ctx) { } if (ctx->parenExpr() != nullptr) { result = getExpr(ctx->parenExpr()->expr()); + result.parenthesized = true; } return result; } Expr getExpr(TocParser::ExprContext * ctx) { Expr result; + result.parenthesized = false; if (ctx->funcExpr() != nullptr) { result.type = ExprType::Func; result._func.functionName = ctx->funcExpr()->funcName()->NAME()->toString(); @@ -242,18 +263,31 @@ Expr getExpr(TocParser::ExprContext * ctx) { } if (ctx->parenExpr() != nullptr) { result = getExpr(ctx->parenExpr()->expr()); + result.parenthesized = true; } if (ctx->accessExpr() != nullptr) { - // TODO: access chain - for (auto sub : ctx->accessExpr()->accessSubExpr()) { + auto firstSub = ctx->accessExpr()->accessSubExpr(0); + if (firstSub->accessMember() != nullptr) { + result.type = ExprType::Dot; + result._dot.expr = std::make_unique(getExpr(ctx->accessExpr()->nonAccessExpr())); + result._dot.ident.name = firstSub->accessMember()->identifierExpr()->varName()->NAME()->toString(); + } + else { + result.type = ExprType::Brackets; + result._brackets.lexpr = std::make_unique(getExpr(ctx->accessExpr()->nonAccessExpr())); + result._brackets.rexpr = std::make_unique(getExpr(firstSub->accessBrackets()->expr())); + } + for (int i = 1; i < ctx->accessExpr()->accessSubExpr().size(); i++) { + Expr tmp = result; + auto sub = ctx->accessExpr()->accessSubExpr(i); if (sub->accessMember() != nullptr) { result.type = ExprType::Dot; - result._dot.expr = std::make_unique(getExpr(ctx->accessExpr()->nonAccessExpr())); + result._dot.expr = std::make_unique(tmp); result._dot.ident.name = sub->accessMember()->identifierExpr()->varName()->NAME()->toString(); } else { result.type = ExprType::Brackets; - result._brackets.lexpr = std::make_unique(getExpr(ctx->accessExpr()->nonAccessExpr())); + result._brackets.lexpr = std::make_unique(tmp); result._brackets.rexpr = std::make_unique(getExpr(sub->accessBrackets()->expr())); } } diff --git a/src/toc.h b/src/toc.h index 6dd611d..0c55466 100644 --- a/src/toc.h +++ b/src/toc.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "repr.h" @@ -41,7 +42,27 @@ std::ostream & operator<< (std::ostream & out, const Type & t) { return out; } std::ostream & operator<< (std::ostream & out, const Variable & v) { - out << v.type << " " << v.name; + out << v.type << " "; + + std::stringstream sstr; + std::string s = v.name; + + for (auto m = v.type.modifiers.rbegin(); m != v.type.modifiers.rend(); m++) { + if (m->type == TypeModifierType::Pointer) { + sstr.str(std::string()); + sstr << "*(" << s << ")"; + s = sstr.str(); + } + else { + sstr.str(std::string()); + sstr << "(" << s << ")["; + if (m->_staticArray) + sstr << m->_arraySize; + sstr << "]"; + s = sstr.str(); + } + } + out << s; return out; } @@ -88,6 +109,9 @@ std::ostream & operator<< (std::ostream & out, const TernaryOperatorExpr & o) { return out; } std::ostream & operator<< (std::ostream & out, const Expr & e) { + if (e.parenthesized) + out << "("; + switch (e.type) { case ExprType::Func: out << e._func.functionName << "(" << e._func.arguments << ")"; break; @@ -110,6 +134,9 @@ std::ostream & operator<< (std::ostream & out, const Expr & e) { case ExprType::TernaryOperator: out << e._ternaryOperator; break; } + + if (e.parenthesized) + out << ")"; return out; } @@ -135,7 +162,7 @@ std::ostream & operator<< (std::ostream & out, const Stmt & s) { case StmtType::While: out << "while (" << s._while.condition << ")\n" << s._while.body; break; case StmtType::Assign: - out << s._assign.name << "=" << s._assign.expr << ";"; break; + out << s._assign.name << " = " << s._assign.expr << ";"; break; case StmtType::Return: out << "return " << s._return.expr << ";"; break; case StmtType::Expr: @@ -161,7 +188,10 @@ void tocStruct (std::ostream & out, const Struct & s, bool stub) { if (stub) { out << ";\n"; for (auto m : s.methods) { - out << m.returnType << " " << s.name << "_" << m.name << " (" << m.parameters << ");\n"; + m.parameters.insert(m.parameters.begin(), {"this", {s.name, {{TypeModifierType::Pointer, false, -1}}}}); + out << m.returnType << " " << + s.name << "_" << m.name << + " (" << m.parameters << ");\n"; } return; } @@ -177,6 +207,7 @@ void tocStruct (std::ostream & out, const Struct & s, bool stub) { out << "};\n"; for (auto m : s.methods) { + m.parameters.insert(m.parameters.begin(), {"this", {s.name, {{TypeModifierType::Pointer, false, -1}}}}); out << m.returnType << " " << s.name << "_" << m.name << " (" << m.parameters << ")\n" << m.body; } } @@ -184,265 +215,17 @@ void tocProgram (std::ostream & out, const Program & p) { for (auto s : p.structs) { tocStruct(out, s, true); } - for (auto s : p.structs) { - tocStruct(out, s, false); + for (auto f : p.functions) { + tocFunction(out, f, true); } for (auto v : p.variables) { out << v << ";\n"; } - - for (auto f : p.functions) { - tocFunction(out, f, true); + for (auto s : p.structs) { + tocStruct(out, s, false); } for (auto f : p.functions) { tocFunction(out, f, false); } } - - - - -// void toc(std::ostream & o, TocParser::ProgContext * ctx) { -// for (auto * decl : ctx->decl()) { -// /**/ if (decl->structDecl() != nullptr) toc_stub(o, decl->structDecl()); -// else if (decl->funcDecl() != nullptr) toc_stub(o, decl->funcDecl()->func()); -// } -// for (auto * decl : ctx->decl()) { -// if (decl->varDecl() != nullptr) { -// toc(o, decl->varDecl()); -// out << ";\n"; -// } -// else if (decl->structDecl() != nullptr) toc(o, decl->structDecl()); -// else if (decl->funcDecl() != nullptr) toc(o, decl->funcDecl()->func()); -// } -// } -// void toc(std::ostream & o, TocParser::VarDeclContext * ctx) { -// o -// << ctx->var()->type()->getText() -// << " " -// << ctx->var()->varName()->getText(); - -// if (ctx->var()->expr() != nullptr) { -// out << " = "; -// toc(o, ctx->var()->expr()); -// } -// } -// void toc(std::ostream & o, TocParser::FuncContext * ctx) { -// o -// << ctx->type()->getText() -// << " " -// << ctx->funcName()->getText() -// << "("; - -// if (ctx->parameter()->firstParameter() != nullptr) { -// o -// << ctx->parameter()->firstParameter()->var()->type()->getText() -// << " " -// << ctx->parameter()->firstParameter()->var()->varName()->getText(); - -// for (auto * par : ctx->parameter()->additionalParameter()) { -// o -// << ", " -// << par->var()->type()->getText() -// << " " -// << par->var()->varName()->getText(); -// } -// } - -// out << ")\n{\n"; - -// toc(o, ctx->body()); - -// out << "}\n"; -// } -// void toc(std::ostream & o, TocParser::StructDeclContext * ctx) { -// o -// << "typedef struct " -// << ctx->structName()->getText() -// << "\n{\n"; - -// for (auto * member : ctx->structMember()) { -// if (member->structVar() != nullptr) { -// o -// << member->structVar()->var()->type()->getText() -// << " " -// << member->structVar()->var()->varName()->getText() -// << ";\n"; -// } -// } -// out << "} " -// << ctx->structName()->getText() -// << ";\n"; -// for (auto * member : ctx->structMember()) { -// if (member->structMethod() != nullptr) { -// o -// << member->structMethod()->func()->type()->getText() -// << " " -// << ctx->structName()->getText() -// << "_" -// << member->structMethod()->func()->funcName()->getText() -// << "(" -// << ctx->structName()->getText() -// << " * this"; - -// if (member->structMethod()->func()->parameter()->firstParameter() != nullptr) { -// o -// << ", " -// << member->structMethod()->func()->parameter()->firstParameter()->var()->type()->getText() -// << " " -// << member->structMethod()->func()->parameter()->firstParameter()->var()->varName()->getText(); - -// for (auto * par : member->structMethod()->func()->parameter()->additionalParameter()) { -// o -// << ", " -// << par->var()->type()->getText() -// << " " -// << par->var()->varName()->getText(); -// } -// } - -// out << ")\n{\n"; - -// toc(o, member->structMethod()->func()->body()); - -// out << "}\n"; -// } -// } -// } -// void toc(std::ostream & o, TocParser::BodyContext * ctx) { -// for (auto * stmt : ctx->stmt()) { -// toc(o, stmt); -// out << "\n"; -// } -// } -// void toc(std::ostream & o, TocParser::StmtContext * ctx) { -// /**/ if (ctx->varDecl() != nullptr) toc(o, ctx->varDecl()); -// else if (ctx->conditional() != nullptr) toc(o, ctx->conditional()->ifCond()); -// else if (ctx->loop() != nullptr) toc(o, ctx->loop()->whileLoop()); -// else if (ctx->assignment() != nullptr) toc(o, ctx->assignment()); -// else if (ctx->returnStmt() != nullptr) toc(o, ctx->returnStmt()); -// else if (ctx->expr() != nullptr) toc(o, ctx->expr()); - -// if (ctx->conditional() == nullptr && ctx->loop() == nullptr) -// out << ";"; -// } -// void toc(std::ostream & o, TocParser::IfCondContext * ctx) { -// out << "if ("; -// toc(o, ctx->expr()); -// out << ")\n{\n"; -// toc(o, ctx->body()); -// out << "}\n"; -// } -// void toc(std::ostream & o, TocParser::WhileLoopContext * ctx) { -// out << "while ("; -// toc(o, ctx->expr()); -// out << ")\n{\n"; -// toc(o, ctx->body()); -// out << "}\n"; -// } -// void toc(std::ostream & o, TocParser::AssignmentContext * ctx) { -// toc(o, ctx->identifier()); -// out << " = "; -// toc(o, ctx->expr()); -// } -// void toc(std::ostream & o, TocParser::ReturnStmtContext * ctx) { -// out << "return "; -// toc(o, ctx->expr()); -// } -// void toc(std::ostream & o, TocParser::ExprContext * ctx) { -// /**/ if (ctx->funcCall() != nullptr) toc(o, ctx->funcCall()); -// else if (ctx->identifier() != nullptr) toc(o, ctx->identifier()); -// else if (ctx->literal() != nullptr) toc(o, ctx->literal()); -// else if (ctx->subscript() != nullptr) toc(o, ctx->subscript()); -// else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess()); -// else if (ctx->parenExpr() != nullptr) toc(o, ctx->parenExpr()); -// else if (ctx->operatorExpr() != nullptr) toc(o, ctx->operatorExpr()->binaryOperator()); -// } -// void toc(std::ostream & o, TocParser::NonOpExprContext * ctx) { -// /**/ if (ctx->funcCall() != nullptr) toc(o, ctx->funcCall()); -// else if (ctx->identifier() != nullptr) toc(o, ctx->identifier()); -// else if (ctx->literal() != nullptr) toc(o, ctx->literal()); -// else if (ctx->subscript() != nullptr) toc(o, ctx->subscript()); -// else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess()); -// else if (ctx->parenExpr() != nullptr) toc(o, ctx->parenExpr()); -// } -// void toc(std::ostream & o, TocParser::NonSubscriptExprContext * ctx) { -// /**/ if (ctx->funcCall() != nullptr) toc(o, ctx->funcCall()); -// else if (ctx->identifier() != nullptr) toc(o, ctx->identifier()); -// else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess()); -// else if (ctx->parenExpr() != nullptr) toc(o, ctx->parenExpr()); -// } -// void toc(std::ostream & o, TocParser::FuncCallContext * ctx) { -// o -// << ctx->funcName()->getText() -// << "("; -// for (int i = 0; i < ctx->expr().size(); i++) { -// if (i != 0) out << ", "; -// toc(o, ctx->expr(i)); -// } -// out << ")"; -// } -// void toc(std::ostream & o, TocParser::IdentifierContext * ctx) { -// out << ctx->getText(); -// } -// void toc(std::ostream & o, TocParser::LiteralContext * ctx) { -// if (ctx->INTLIT() != nullptr) out << ctx->INTLIT()->getText(); -// } -// void toc(std::ostream & o, TocParser::SubscriptContext * ctx) { -// toc(o, ctx->nonSubscriptExpr()); -// out << "["; -// toc(o, ctx->expr()); -// out << "]"; -// } -// void toc(std::ostream & o, TocParser::MemberAccessContext * ctx) { -// toc(o, ctx->identifier(0)); -// out << "."; -// toc(o, ctx->identifier(1)); -// } -// void toc(std::ostream & o, TocParser::ParenExprContext * ctx) { -// out << "("; -// toc(o, ctx->expr()); -// out << ")"; -// } -// void toc(std::ostream & o, TocParser::BinaryOperatorContext * ctx) { -// for (int i = 0; i < ctx->BINARY_OPERATOR().size(); i++) { -// toc(o, ctx->nonOpExpr(i)); -// o -// << " " -// << ctx->BINARY_OPERATOR(i)->getText() -// << " "; -// toc(o, ctx->nonOpExpr(i + 1)); -// } -// } - -// void toc_stub(std::ostream & o, TocParser::FuncContext * ctx) { -// o -// << ctx->type()->getText() -// << " " -// << ctx->funcName()->getText() -// << "("; - -// if (ctx->parameter()->firstParameter() != nullptr) { -// o -// << ctx->parameter()->firstParameter()->var()->type()->getText() -// << " " -// << ctx->parameter()->firstParameter()->var()->varName()->getText(); - -// for (auto * par : ctx->parameter()->additionalParameter()) { -// o -// << ", " -// << par->var()->type()->getText() -// << " " -// << par->var()->varName()->getText(); -// } -// } - -// out << ");\n"; -// } -// void toc_stub(std::ostream & o, TocParser::StructDeclContext * ctx) { -// o -// << "struct " -// << ctx->structName()->getText() -// << ";\n"; -// } -- cgit v1.2.3