I am building a Typechecker and in order to pass taks 1, i would need to implement the base, does someone know what that means? I think my Typechecker.H (previously named Skeleton.H) but i do not know if that is enough to be considered the base
Here is my Typechecker.C
#include "Typechecker.H"
#include <iostream>
void SymbolTable::enterScope() {
scopes.push_back(std::map<std::string, Symbol>());
}
void SymbolTable::leaveScope() {
if (!scopes.empty()) {
scopes.pop_back();
}
}
bool SymbolTable::insert(const std::string& name, const Symbol& symbol) {
if (scopes.empty()) return false;
return scopes.back().insert({name, symbol}).second;
}
Symbol SymbolTable::lookup(const std::string& name) {
for (auto it = scopes.rbegin(); it != scopes.rend(); ++it) {
auto found = it->find(name);
if (found != it->end()) return found->second;
}
return Symbol(TError);
}
void Skeleton::visitProgram(Program *t) {} //abstract class
void Skeleton::visitDef(Def *t) {} //abstract class
void Skeleton::visitField(Field *t) {} //abstract class
void Skeleton::visitArg(Arg *t) {} //abstract class
void Skeleton::visitStm(Stm *t) {} //abstract class
void Skeleton::visitIdIn(IdIn *t) {} //abstract class
void Skeleton::visitExp(Exp *t) {} //abstract class
void Skeleton::visitType(Type *t) {} //abstract class
void Skeleton::visitPDefs(PDefs *p_defs)
{
/* Code For PDefs Goes Here */
if (p_defs->listdef_) p_defs->listdef_->accept(this);
}
void Skeleton::visitDFun(DFun *d_fun)
{
/* Code For DFun Goes Here */
if (d_fun->type_) d_fun->type_->accept(this);
visitId(d_fun->id_);
if (d_fun->listarg_) d_fun->listarg_->accept(this);
if (d_fun->liststm_) d_fun->liststm_->accept(this);
}
void Skeleton::visitDStruct(DStruct *d_struct)
{
/* Code For DStruct Goes Here */
visitId(d_struct->id_);
if (d_struct->listfield_) d_struct->listfield_->accept(this);
}
void Skeleton::visitDStructDer(DStructDer *d_struct_der)
{
/* Code For DStructDer Goes Here */
visitId(d_struct_der->id_);
if (d_struct_der->type_) d_struct_der->type_->accept(this);
if (d_struct_der->listfield_) d_struct_der->listfield_->accept(this);
}
void Skeleton::visitFDecl(FDecl *f_decl)
{
/* Code For FDecl Goes Here */
if (f_decl->type_) f_decl->type_->accept(this);
visitId(f_decl->id_);
}
void Skeleton::visitADecl(ADecl *a_decl)
{
/* Code For ADecl Goes Here */
if (a_decl->type_) a_decl->type_->accept(this);
visitId(a_decl->id_);
}
void Skeleton::visitSExp(SExp *s_exp)
{
/* Code For SExp Goes Here */
if (s_exp->exp_) s_exp->exp_->accept(this);
}
void Skeleton::visitSDecls(SDecls *s_decls)
{
/* Code For SDecls Goes Here */
if (s_decls->type_) s_decls->type_->accept(this);
if (s_decls->listidin_) s_decls->listidin_->accept(this);
}
void Skeleton::visitSReturn(SReturn *s_return)
{
/* Code For SReturn Goes Here */
if (s_return->exp_) s_return->exp_->accept(this);
}
void Skeleton::visitSReturnV(SReturnV *s_return_v)
{
/* Code For SReturnV Goes Here */
currentType = TVoid;
}
void Skeleton::visitSWhile(SWhile *s_while)
{
/* Code For SWhile Goes Here */
if (s_while->exp_) s_while->exp_->accept(this);
if (s_while->stm_) s_while->stm_->accept(this);
}
void Skeleton::visitSDoWhile(SDoWhile *s_do_while)
{
/* Code For SDoWhile Goes Here */
if (s_do_while->stm_) s_do_while->stm_->accept(this);
if (s_do_while->exp_) s_do_while->exp_->accept(this);
}
void Skeleton::visitSFor(SFor *s_for)
{
/* Code For SFor Goes Here */
if (s_for->exp_1) s_for->exp_1->accept(this); //initialization
if (s_for->exp_2) s_for->exp_2->accept(this); //condition
if (s_for->exp_3) s_for->exp_3->accept(this); //increase
if (s_for->stm_) s_for->stm_->accept(this); //loop's body
}
void Skeleton::visitSBlock(SBlock *s_block)
{
/* Code For SBlock Goes Here */
if (s_block->liststm_) s_block->liststm_->accept(this);
}
void Skeleton::visitSIfElse(SIfElse *s_if_else)
{
/* Code For SIfElse Goes Here */
if (s_if_else->exp_) s_if_else->exp_->accept(this);
if (s_if_else->stm_1) s_if_else->stm_1->accept(this);
if (s_if_else->stm_2) s_if_else->stm_2->accept(this);
}
void Skeleton::visitSTry(STry *s_try)
{
/* Code For STry Goes Here */
if (s_try->stm_1) s_try->stm_1->accept(this);
if (s_try->type_) s_try->type_->accept(this);
visitId(s_try->id_);
if (s_try->stm_2) s_try->stm_2->accept(this);
}
void Skeleton::visitIdNoInit(IdNoInit *id_no_init)
{
/* Code For IdNoInit Goes Here */
visitId(id_no_init->id_);
}
void Skeleton::visitIdInit(IdInit *id_init)
{
/* Code For IdInit Goes Here */
visitId(id_init->id_);
if (id_init->exp_) id_init->exp_->accept(this);
}
void Skeleton::visitETrue(ETrue *e_true)
{
/* Code For ETrue Goes Here */
}
void Skeleton::visitEFalse(EFalse *e_false)
{
/* Code For EFalse Goes Here */
}
void Skeleton::visitEInt(EInt *e_int)
{
/* Code For EInt Goes Here */
visitInteger(e_int->integer_);
}
void Skeleton::visitEDouble(EDouble *e_double)
{
/* Code For EDouble Goes Here */
visitDouble(e_double->double_);
}
void Skeleton::visitEId(EId *e_id)
{
/* Code For EId Goes Here */
visitId(e_id->id_);
}
void Skeleton::visitEApp(EApp *e_app)
{
/* Code For EApp Goes Here */
visitId(e_app->id_);
if (e_app->listexp_) e_app->listexp_->accept(this);
}
void Skeleton::visitEProj(EProj *e_proj)
{
/* Code For EProj Goes Here */
if (e_proj->exp_) e_proj->exp_->accept(this);
visitId(e_proj->id_);
}
void Skeleton::visitEPIncr(EPIncr *ep_incr)
{
/* Code For EPIncr Goes Here */
if (ep_incr->exp_) ep_incr->exp_->accept(this);
}
void Skeleton::visitEPDecr(EPDecr *ep_decr)
{
/* Code For EPDecr Goes Here */
if (ep_decr->exp_) ep_decr->exp_->accept(this);
}
void Skeleton::visitEIncr(EIncr *e_incr)
{
/* Code For EIncr Goes Here */
if (e_incr->exp_) e_incr->exp_->accept(this);
}
void Skeleton::visitEDecr(EDecr *e_decr)
{
/* Code For EDecr Goes Here */
if (e_decr->exp_) e_decr->exp_->accept(this);
}
void Skeleton::visitEUPlus(EUPlus *eu_plus)
{
/* Code For EUPlus Goes Here */
if (eu_plus->exp_) eu_plus->exp_->accept(this);
}
void Skeleton::visitEUMinus(EUMinus *eu_minus)
{
/* Code For EUMinus Goes Here */
if (eu_minus->exp_) eu_minus->exp_->accept(this);
}
void Skeleton::visitETimes(ETimes *e_times)
{
/* Code For ETimes Goes Here */
if (e_times->exp_1) e_times->exp_1->accept(this);
if (e_times->exp_2) e_times->exp_2->accept(this);
}
void Skeleton::visitEDiv(EDiv *e_div)
{
/* Code For EDiv Goes Here */
if (e_div->exp_1) e_div->exp_1->accept(this);
if (e_div->exp_2) e_div->exp_2->accept(this);
}
void Skeleton::visitEPlus(EPlus *e_plus)
{
/* Code For EPlus Goes Here */
if (e_plus->exp_1) e_plus->exp_1->accept(this);
if (e_plus->exp_2) e_plus->exp_2->accept(this);
}
void Skeleton::visitEMinus(EMinus *e_minus)
{
/* Code For EMinus Goes Here */
if (e_minus->exp_1) e_minus->exp_1->accept(this);
if (e_minus->exp_2) e_minus->exp_2->accept(this);
}
void Skeleton::visitETwc(ETwc *e_twc)
{
/* Code For ETwc Goes Here */
if (e_twc->exp_1) e_twc->exp_1->accept(this);
if (e_twc->exp_2) e_twc->exp_2->accept(this);
}
void Skeleton::visitELt(ELt *e_lt)
{
/* Code For ELt Goes Here */
if (e_lt->exp_1) e_lt->exp_1->accept(this);
if (e_lt->exp_2) e_lt->exp_2->accept(this);
}
void Skeleton::visitEGt(EGt *e_gt)
{
/* Code For EGt Goes Here */
if (e_gt->exp_1) e_gt->exp_1->accept(this);
if (e_gt->exp_2) e_gt->exp_2->accept(this);
}
void Skeleton::visitELtEq(ELtEq *e_lt_eq)
{
/* Code For ELtEq Goes Here */
if (e_lt_eq->exp_1) e_lt_eq->exp_1->accept(this);
if (e_lt_eq->exp_2) e_lt_eq->exp_2->accept(this);
}
void Skeleton::visitEGtEq(EGtEq *e_gt_eq)
{
/* Code For EGtEq Goes Here */
if (e_gt_eq->exp_1) e_gt_eq->exp_1->accept(this);
if (e_gt_eq->exp_2) e_gt_eq->exp_2->accept(this);
}
void Skeleton::visitEEq(EEq *e_eq)
{
/* Code For EEq Goes Here */
if (e_eq->exp_1) e_eq->exp_1->accept(this);
if (e_eq->exp_2) e_eq->exp_2->accept(this);
}
void Skeleton::visitENEq(ENEq *en_eq)
{
/* Code For ENEq Goes Here */
if (en_eq->exp_1) en_eq->exp_1->accept(this);
if (en_eq->exp_2) en_eq->exp_2->accept(this);
}
void Skeleton::visitEAnd(EAnd *e_and)
{
/* Code For EAnd Goes Here */
if (e_and->exp_1) e_and->exp_1->accept(this);
if (e_and->exp_2) e_and->exp_2->accept(this);
}
void Skeleton::visitEOr(EOr *e_or)
{
/* Code For EOr Goes Here */
if (e_or->exp_1) e_or->exp_1->accept(this);
if (e_or->exp_2) e_or->exp_2->accept(this);
}
void Skeleton::visitEAss(EAss *e_ass)
{
/* Code For EAss Goes Here */
if (e_ass->exp_1) e_ass->exp_1->accept(this);
if (e_ass->exp_2) e_ass->exp_2->accept(this);
}
void Skeleton::visitECond(ECond *e_cond)
{
/* Code For ECond Goes Here */
if (e_cond->exp_1) e_cond->exp_1->accept(this);
if (e_cond->exp_2) e_cond->exp_2->accept(this);
if (e_cond->exp_3) e_cond->exp_3->accept(this);
}
void Skeleton::visitEThrow(EThrow *e_throw)
{
/* Code For EThrow Goes Here */
if (e_throw->exp_) e_throw->exp_->accept(this);
}
void Skeleton::visitType_bool(Type_bool *type_bool)
{
/* Code For Type_bool Goes Here */
}
void Skeleton::visitType_int(Type_int *type_int)
{
/* Code For Type_int Goes Here */
}
void Skeleton::visitType_double(Type_double *type_double)
{
/* Code For Type_double Goes Here */
}
void Skeleton::visitType_void(Type_void *type_void)
{
/* Code For Type_void Goes Here */
}
void Skeleton::visitType_exception(Type_exception *type_exception)
{
/* Code For Type_exception Goes Here */
}
void Skeleton::visitTypeId(TypeId *type_id)
{
/* Code For TypeId Goes Here */
visitId(type_id->id_);
}
void Skeleton::visitListDef(ListDef *list_def)
{
for (ListDef::iterator i = list_def->begin() ; i != list_def->end() ; ++i)
{
(*i)->accept(this);
}
}
void Skeleton::visitListField(ListField *list_field)
{
for (ListField::iterator i = list_field->begin() ; i != list_field->end() ; ++i)
{
(*i)->accept(this);
}
}
void Skeleton::visitListArg(ListArg *list_arg)
{
for (ListArg::iterator i = list_arg->begin() ; i != list_arg->end() ; ++i)
{
(*i)->accept(this);
}
}
void Skeleton::visitListStm(ListStm *list_stm)
{
for (ListStm::iterator i = list_stm->begin() ; i != list_stm->end() ; ++i)
{
(*i)->accept(this);
}
}
void Skeleton::visitListIdIn(ListIdIn *list_id_in)
{
for (ListIdIn::iterator i = list_id_in->begin() ; i != list_id_in->end() ; ++i)
{
(*i)->accept(this);
}
}
void Skeleton::visitListExp(ListExp *list_exp)
{
for (ListExp::iterator i = list_exp->begin() ; i != list_exp->end() ; ++i)
{
(*i)->accept(this);
}
}
void Skeleton::visitListId(ListId *list_id)
{
for (ListId::iterator i = list_id->begin() ; i != list_id->end() ; ++i)
{
visitId(*i) ;
}
}
ValueType Skeleton::inferType(Type *p) {
p->accept(this);
return currentType;
}
void Skeleton::visitInteger(Integer x)
{
/* Code for Integer Goes Here */
currentType = TInt;
}
void Skeleton::visitChar(Char x)
{
/* Code for Char Goes Here */
currentType = TInt;
}
void Skeleton::visitDouble(Double x)
{
/* Code for Double Goes Here */
currentType = TDouble;
}
void Skeleton::visitString(String x)
{
/* Code for String Goes Here */
currentType = TError;
}
void Skeleton::visitIdent(Ident x)
{
/* Code for Ident Goes Here */
Symbol sym = symbolTable.lookup(x);
currentType = sym.type;
}
void Skeleton::visitId(Id x)
{
/* Code for Id Goes Here */
Symbol sym = symbolTable.lookup(x);
currentType = sym.type;
}
Here is my Typechecker.H:
#include "Absyn.H"
#include <map>
#include <string>
#include <vector>
enum ValueType { TInt, TBool, TVoid, TDouble, TError };
struct Symbol {
ValueType type;
Symbol(ValueType t) : type(t) {}
};
class SymbolTable {
private:
std::vector<std::map<std::string, Symbol>> scopes;
public:
void enterScope();
void leaveScope();
bool insert(const std::string& name, const Symbol& symbol);
Symbol lookup(const std::string& name);
};
class Skeleton : public Visitor
{
private:
SymbolTable symbolTable;
ValueType currentType;
public:
void visitProgram(Program *p);
void visitDef(Def *p);
void visitField(Field *p);
void visitArg(Arg *p);
void visitStm(Stm *p);
void visitIdIn(IdIn *p);
void visitExp(Exp *p);
void visitType(Type *p);
void visitPDefs(PDefs *p);
void visitDFun(DFun *p);
void visitDStruct(DStruct *p);
void visitDStructDer(DStructDer *p);
void visitFDecl(FDecl *p);
void visitADecl(ADecl *p);
void visitSExp(SExp *p);
void visitSDecls(SDecls *p);
void visitSReturn(SReturn *p);
void visitSReturnV(SReturnV *p);
void visitSWhile(SWhile *p);
void visitSDoWhile(SDoWhile *p);
void visitSFor(SFor *p);
void visitSBlock(SBlock *p);
void visitSIfElse(SIfElse *p);
void visitSTry(STry *p);
void visitIdNoInit(IdNoInit *p);
void visitIdInit(IdInit *p);
void visitETrue(ETrue *p);
void visitEFalse(EFalse *p);
void visitEInt(EInt *p);
void visitEDouble(EDouble *p);
void visitEId(EId *p);
void visitEApp(EApp *p);
void visitEProj(EProj *p);
void visitEPIncr(EPIncr *p);
void visitEPDecr(EPDecr *p);
void visitEIncr(EIncr *p);
void visitEDecr(EDecr *p);
void visitEUPlus(EUPlus *p);
void visitEUMinus(EUMinus *p);
void visitETimes(ETimes *p);
void visitEDiv(EDiv *p);
void visitEPlus(EPlus *p);
void visitEMinus(EMinus *p);
void visitETwc(ETwc *p);
void visitELt(ELt *p);
void visitEGt(EGt *p);
void visitELtEq(ELtEq *p);
void visitEGtEq(EGtEq *p);
void visitEEq(EEq *p);
void visitENEq(ENEq *p);
void visitEAnd(EAnd *p);
void visitEOr(EOr *p);
void visitEAss(EAss *p);
void visitECond(ECond *p);
void visitEThrow(EThrow *p);
void visitType_bool(Type_bool *p);
void visitType_int(Type_int *p);
void visitType_double(Type_double *p);
void visitType_void(Type_void *p);
void visitType_exception(Type_exception *p);
void visitTypeId(TypeId *p);
void visitListDef(ListDef *p);
void visitListField(ListField *p);
void visitListArg(ListArg *p);
void visitListStm(ListStm *p);
void visitListIdIn(ListIdIn *p);
void visitListExp(ListExp *p);
void visitListId(ListId *p);
void visitInteger(Integer x);
void visitChar(Char x);
void visitDouble(Double x);
void visitString(String x);
void visitIdent(Ident x);
void visitId(Id x);
private:
SymbolTable symbolTable;
ValueType currentType;
ValueType inferType(Type *p);
};
#endif
And here is my CPP.cf:
PDefs. Program ::= [Def] ;
DFun. Def ::= Type Id "(" [Arg] ")" "{" [Stm] "}" ;
DStruct. Def ::= "struct" Id "{" [Field] "}" ";" ;
DStructDer. Def ::= "struct" Id ":" Type "{" [Field] "}" ";" ;
terminator Def "" ;
FDecl. Field ::= Type Id ;
terminator nonempty Field ";" ;
ADecl. Arg ::= Type Id ;
separator Arg "," ;
SExp. Stm ::= Exp ";" ;
SDecls. Stm ::= Type [IdIn] ";" ;
SReturn. Stm ::= "return" Exp ";" ;
SReturnV. Stm ::= "return" ";" ;
SWhile. Stm ::= "while" "(" Exp ")" Stm ;
SDoWhile. Stm ::= "do" Stm "while" "(" Exp ")" ";" ;
SFor. Stm ::= "for" "(" Exp ";" Exp ";" Exp ")" Stm ;
SBlock. Stm ::= "{" [Stm] "}" ;
SIfElse. Stm ::= "if" "(" Exp ")" Stm "else" Stm ;
STry. Stm ::= "try" Stm "catch" "(" Type Id ")" Stm ;
terminator Stm "" ;
IdNoInit. IdIn ::= Id ;
IdInit. IdIn ::= Id "=" Exp ;
separator nonempty IdIn "," ;
ETrue. Exp15 ::= "true" ;
EFalse. Exp15 ::= "false" ;
EInt. Exp15 ::= Integer ;
EDouble. Exp15 ::= Double ;
EId. Exp15 ::= Id ;
EApp. Exp14 ::= Id "(" [Exp] ")" ;
EProj. Exp14 ::= Exp14 "." Id ;
EPIncr. Exp14 ::= Exp14 "++" ;
EPDecr. Exp14 ::= Exp14 "--" ;
EIncr. Exp13 ::= "++" Exp13 ;
EDecr. Exp13 ::= "--" Exp13 ;
EUPlus. Exp13 ::= "+" Exp13 ;
EUMinus. Exp13 ::= "-" Exp13 ;
ETimes. Exp12 ::= Exp12 "*" Exp13 ;
EDiv. Exp12 ::= Exp12 "/" Exp13 ;
EPlus. Exp11 ::= Exp11 "+" Exp12 ;
EMinus. Exp11 ::= Exp11 "-" Exp12 ;
ETwc. Exp10 ::= Exp10 "<=>" Exp11 ;
ELt. Exp9 ::= Exp9 "<" Exp10 ;
EGt. Exp9 ::= Exp9 ">" Exp10 ;
ELtEq. Exp9 ::= Exp9 "<=" Exp10 ;
EGtEq. Exp9 ::= Exp9 ">=" Exp10 ;
EEq. Exp8 ::= Exp8 "==" Exp9 ;
ENEq. Exp8 ::= Exp8 "!=" Exp9 ;
EAnd. Exp4 ::= Exp4 "&&" Exp5 ;
EOr. Exp3 ::= Exp3 "||" Exp4 ;
EAss. Exp2 ::= Exp3 "=" Exp2 ;
ECond. Exp2 ::= Exp3 "?" Exp ":" Exp2 ;
EThrow. Exp1 ::= "throw" Exp1 ;
coercions Exp 15 ;
separator Exp "," ;
rules Type ::= "bool" | "int" | "double" | "void" | "exception" | Id ;
token Id (letter (letter | digit | '_')*) ;
separator nonempty Id "," ;
comment "#" ;
comment "//" ;
comment "/*" "*/" ;
Thank you in advance! – Lucy 😀
I have tried implementing scopes and also creating different classes, also i am getting some errors with the CPP.y but that is not so important. I have added some functions, but i am not sure what more to add for the base to be done
New contributor
0