S_table E_base_venv(void) { S_table t = S_empty(); S_enter( t, S_Symbol("print"), E_FunEntry(Ty_TyList(Ty_String(), NULL), Ty_Void()) ); S_enter( t, S_Symbol("flush"), E_FunEntry(NULL, Ty_Void()) ); S_enter( t, S_Symbol("getchar"), E_FunEntry(NULL, Ty_String()) ); S_enter( t, S_Symbol("ord"), E_FunEntry(Ty_TyList(Ty_String(), NULL), Ty_Int()) ); S_enter( t, S_Symbol("chr"), E_FunEntry(Ty_TyList(Ty_Int(), NULL), Ty_String()) ); S_enter( t, S_Symbol("size"), E_FunEntry(Ty_TyList(Ty_String(), NULL), Ty_Int()) ); S_enter( t, S_Symbol("substring"), E_FunEntry(Ty_TyList(Ty_String(), Ty_TyList(Ty_Int(), Ty_TyList(Ty_Int(), NULL))), Ty_String()) ); S_enter( t, S_Symbol("concat"), E_FunEntry(Ty_TyList(Ty_String(), Ty_TyList(Ty_String(), NULL)), Ty_String()) ); S_enter( t, S_Symbol("not"), E_FunEntry(Ty_TyList(Ty_Int(), NULL), Ty_Int()) ); S_enter( t, S_Symbol("exit"), E_FunEntry(Ty_TyList(Ty_Int(), NULL), Ty_Void()) ); return t; }
Tr_exp transDec_functionDec(Tr_level level, S_table venv, S_table tenv, A_dec d, Temp_label breakk) { for (A_fundecList fundecs = d->u.function; fundecs; fundecs = fundecs->tail) { S_symbol name = fundecs->head->name; Ty_tyList formals = makeFormalTyList(tenv, fundecs->head->params); for (A_fundecList f = d->u.function; f != fundecs; f = f->tail) if (f->head->name == name) EM_error(f->head->pos, "there are two functions with the same name in the same batch " "of mutually recursive functions"); Ty_ty result = (fundecs->head->result)? S_look(tenv, fundecs->head->result) : Ty_Void(); Temp_label label = Temp_newlabel(); U_boolList escapeList = NULL; for (A_fieldList l = fundecs->head->params; l; l = l->tail) // todo: handle no escape escapeList = U_BoolList(TRUE, escapeList); S_enter(venv, name, E_FunEntry(Tr_newLevel(level, label, escapeList), label, formals, result)); } for (A_fundecList fundecs = d->u.function; fundecs; fundecs = fundecs->tail) { S_symbol name = fundecs->head->name; E_enventry x = S_look(venv, name); Ty_tyList formals = x->u.fun.formals; Ty_ty result = x->u.fun.result; Tr_level lev = x->u.fun.level; S_beginScope(venv); { A_fieldList l; Ty_tyList t; Tr_accessList a; for (l = fundecs->head->params, t = formals, a = Tr_formals(lev); l; l = l->tail, t = t->tail, a = a->tail) S_enter(venv, l->head->name, E_VarEntry(a->head, t->head)); // check return type struct expty body = transExp(lev, venv, tenv, fundecs->head->body, breakk); if (!has_same_ty(result, body.ty)) { if (has_same_ty(result, Ty_Void())) EM_error(fundecs->head->pos, "procedure returns value '%s'", type_msg(body.ty)); else EM_error(fundecs->head->pos, "return type mismatched '%s' and '%s')", type_msg(result), type_msg(body.ty)); } Tr_procEntryExit(lev, body.exp, a); } S_endScope(venv); } return Tr_noExp(); }
/* translate function declaration * TODO * reduce the result type from the body and check that * it maps the specified result(including the void case * -it is a procedure) */ void transFuncDec(S_table venv, S_table tenv, A_dec d) { // add the function itself Ty_ty resultTy; if (d->u.function.result) resultTy = S_look(tenv, d->u.function.result); else resultTy = Ty_Void(); Ty_tyList formalTys = makeFormalTyList(tenv, d->u.function.params); S_enter(venv, d->u.function.name, E_FunEntry(formalTys, resultTy)); // re-parse the formal params and add them as variable // binding for the body S_beginScope(venv); A_fieldList fl = d->u.function.params; Ty_tyList tl = formalTys; for (; fl; fl = fl->tail, tl = tl->tail) { S_enter(venv, fl->head->name, E_VarEntry(tl->head)); } transExp(venv, tenv, d->u.function.body); S_endScope(venv); }
void transDec(S_table venv, S_table tenv, A_dec d) { if(d == NULL) { return; } switch(d->kind) { case A_varDec: { struct expty e = transExp(venv, tenv, d->u.var.init); S_enter(venv, d->u.var.var, E_VarEntry(e.ty)); break; } case A_typeDec: { S_enter(venv, d->u.type->head->name, transTy(tenv, d->u.type->head->ty)); break; } case A_functionDec: { A_fundec f = d->u.function->head; Ty_ty resultTy = S_look(tenv, f->result); Ty_tyList formalTys = makeFormalTyList(tenv, f->params); S_enter(venv, f->name, E_FunEntry(formalTys, resultTy)); S_beginScope(venv); { A_fieldList l; Ty_tyList t; for (l = f->params, t = formalTys; l; l = l->tail, t = t->tail) { S_enter(venv, l->head->name, E_VarEntry(t->head)); } } transExp(venv, tenv, d->u.function->head->body); S_endScope(venv); break; } default: { assert(0); } } }
void transDec (S_table venv, S_table tenv, A_dec d) { switch (d->kind) { case A_varDec: { Ty_ty typ = NULL; if (d->u.var.typ) { typ = S_look(tenv, d->u.var.typ); } struct expty e = transExp (venv, tenv, d->u.var.init); if (!typ || typ->kind == e.ty->kind) { if (e.ty->kind == Ty_nil && (!typ || typ->kind != Ty_record)) { EM_error (d->u.var.init->pos, "nil should be constrained by record"); } S_enter (venv, d->u.var.var, E_VarEntry (e.ty)); } else { EM_error (d->u.var.init->pos, "var type should be same as init"); } break; } case A_typeDec: { A_nametyList nList = NULL; for (nList = d->u.type; nList; nList = nList->tail) { bool flag; A_nametyList scanList = NULL; for (scanList = nList->tail; scanList; scanList = scanList->tail) { if (strcmp(S_name(nList->head->name), S_name(scanList->head->name)) == 0) { flag = TRUE; break; } } if (flag) { EM_error (d->pos, "type redefined error"); } S_enter(tenv, nList->head->name, Ty_Name (nList->head->ty->u.name, NULL)); } for (nList = d->u.type; nList; nList = nList->tail) { Ty_ty waitFill = S_look(tenv, nList->head->name); if (waitFill->kind == Ty_name) { waitFill->u.name.ty = transTy (tenv, nList->head->ty); } Ty_ty trueType = actual_ty(waitFill); if (trueType) { S_enter(tenv, nList->head->name, actual_ty(waitFill)); } else { EM_error (d->pos, "recursive types should through record or array"); break; } } break; } case A_functionDec: { A_fundecList funList = NULL; for (funList = d->u.function; funList; funList = funList->tail) { bool flag; A_fundecList scanList = NULL; for (scanList = funList->tail; scanList; scanList = scanList->tail) { if (strcmp(S_name(funList->head->name), S_name(scanList->head->name)) == 0) { flag = TRUE; break; } } if (flag) { EM_error (d->pos, "function redefined error"); } A_fundec f = funList->head; if (!f->result) { f->result = S_Symbol("void"); } Ty_ty resultTy = S_look (tenv, f->result); Ty_tyList formalTys = makeFormalTyList (tenv, f->params); S_enter (venv, f->name, E_FunEntry (formalTys, resultTy)); } for (funList = d->u.function; funList; funList = funList->tail) { A_fundec f = funList->head; Ty_tyList formalTys = makeFormalTyList (tenv, f->params); S_beginScope (venv); { A_fieldList l; Ty_tyList t; for (l = f->params, t = formalTys; l; l = l->tail, t = t->tail) { S_enter (venv, l->head->name, E_VarEntry (t->head)); } } Ty_ty returnTy = S_look (tenv, f->result); if (returnTy->kind != transExp (venv, tenv, f->body).ty->kind) { EM_error (f->body->pos, "return type wrong"); } S_endScope (venv); } break; } } }
void transDec(S_table venv, S_table tenv, A_dec d) { if (!d) { return; } switch (d->kind) { case A_varDec: { struct expty e = transExp(venv, tenv, d->u.var.init); if (d->u.var.typ) { Ty_ty ty = (Ty_ty)S_look(tenv, d->u.var.typ); if (!ty) { EM_error(d->pos, "undefined type '%s'", S_name(d->u.var.typ)); return; } ty = actual_ty(ty); if (!isSameTy(ty, e.ty)) { EM_error(d->pos, (string)"type mismatch"); return; } S_enter(venv, d->u.var.var, E_VarEntry(ty)); return; } if (e.ty->kind == Ty_nil) { EM_error(d->pos, "initializing nil expressions not constrained by record type"); return; } S_enter(venv, d->u.var.var, E_VarEntry(e.ty)); return; } case A_typeDec: { S_table tmp = S_empty(); A_nametyList ntl; for (ntl = d->u.type; ntl; ntl = ntl->tail) { if (S_look(tmp, ntl->head->name)) { EM_error(d->pos, "type '%s' redefined", S_name(ntl->head->name)); return; } S_enter(tmp, ntl->head->name, "-tmp-"); S_enter(tenv, ntl->head->name, Ty_Name(ntl->head->name, NULL)); } for (ntl = d->u.type; ntl; ntl = ntl->tail) { Ty_ty ty = (Ty_ty)S_look(tenv, ntl->head->name); ty->u.name.ty = transTy(tenv, ntl->head->ty); } for (ntl = d->u.type; ntl; ntl = ntl->tail) { Ty_ty ty = (Ty_ty)S_look(tenv, ntl->head->name); if (ty->u.name.ty->kind != Ty_name) { return; } } EM_error(d->pos, "infinite recursive"); return; } case A_functionDec: { S_table tmp = S_empty(); A_fundecList fdl; for (fdl = d->u.function; fdl; fdl = fdl->tail) { if (S_look(tmp, fdl->head->name)) { EM_error(d->pos, "function '%s' redefined", S_name(fdl->head->name)); return; } S_enter(tmp, fdl->head->name, "-tmp-"); } for (fdl = d->u.function; fdl; fdl = fdl->tail) { Ty_tyList formalTys = makeFormalTyList(tenv, fdl->head->params); if (fdl->head->result) { Ty_ty resultTy = S_look(tenv, fdl->head->result); S_enter(venv, fdl->head->name, E_FunEntry(formalTys, resultTy)); } else { S_enter(venv, fdl->head->name, E_FunEntry(formalTys, NULL)); } } for (fdl = d->u.function; fdl; fdl = fdl->tail) { Ty_tyList formalTys = makeFormalTyList(tenv, fdl->head->params); S_beginScope(venv); { A_fieldList l; Ty_tyList t; for (l = fdl->head->params, t = formalTys; l; l = l->tail, t = t->tail) { S_enter(venv, l->head->name, E_VarEntry(t->head)); } } transExp(venv, tenv, fdl->head->body); S_endScope(venv); } break; } default: { assert(0); } } }
struct expty transDec(S_table venv, S_table tenv, A_dec d) { switch( d->kind ) { case A_functionDec: { //whether already in funcdeclar if(InFunc()) EM_error( d->pos , "already in func declare"); A_fundecList funcs = d->u.function; // for every fun declare in fundecList for( ; funcs != NULL ; funcs = funcs->tail ) { A_fundec func = funcs->head; // get ty of params and result Ty_tyList funentry = makeFormalTyList( tenv , func->params ); Ty_ty res; if( func->result == NULL ) res = Ty_Nil(); else res = S_look( tenv , func->result ); if( res == NULL ) EM_error( func->pos , "no " , S_name( func->result ) , "type "); //whether already defined if( S_look( venv , func->name ) != NULL ) EM_error( func->pos , S_name( func->result ) , "already defined" ); S_enter( venv , func->name , E_FunEntry( funentry , res ) ); } funcs = d->u.function; // for every fun in fundecList, call tranexp on its body for( ; funcs != NULL ; funcs = funcs->tail ) { A_fundec func = funcs->head; S_beginScope( venv ); A_fieldList args = func->params; Ty_tyList funentries = ((E_entry)S_look( venv , func->name )) ->fun.formalTys ; for( ; args != NULL ; args = args->tail , funentries = funentries->tail) { A_field arg = args->head; Ty_ty type = funentries->head; S_enter( venv , arg->name , type ); } SetInFunc(); transExp( venv , tenv , func->body ); UsetInFunc(); S_endScope( venv ); } return _expTy( NULL , Ty_Void() ); } case A_varDec: { Ty_ty type = S_look( tenv , d->u.var.typ ); if( type == NULL ) EM_error( d->pos , S_name( d->u.var.typ ) , " not defined " ); struct expty init = transExp( venv , tenv , d->u.var.init ); if( init.ty->kind != Ty_nil && init.ty->kind != type->kind ) EM_error( d->pos , "Expect " , tyKindName( type->kind ) , " but " , tyKindName( init.ty->kind ) ); if( S_look( venv , d->u.var.var ) != NULL ) EM_error( d->pos , S_name( d->u.var.var ) , " already defined " ); S_enter( venv , d->u.var.var , type ); return _expTy( NULL , Ty_Void() ); } case A_typeDec: { A_nametyList tylist = d->u.type; for( ; tylist != NULL ; tylist = tylist->tail ) { A_namety tydec = tylist->head; if( S_look( tenv , tydec->name ) != NULL ) EM_error( tydec->ty->pos , S_name( tydec->name ) , " already declared " ); A_ty ty = tydec->ty; switch( ty->kind ) { case A_nameTy: { Ty_ty tyy = S_look( tenv , ty->u.name ) ; if( tyy == NULL ) S_enter( tenv , tydec->name , Ty_Name( ty->u.name , NULL ) ); else S_enter( tenv , tydec->name , tyy ); } case A_recordTy: { A_fieldList records = ty->u.record; Ty_fieldList types = dfsRecordTy( tenv , records ); S_enter( tenv , tydec->name , Ty_Record( types ) ); } case A_arrayTy: default: assert(0); } S_enter( tenv , tydec->name , E_VarEntry( NULL ) ); } tylist = d->u.type; for( ; tylist != NULL ; tylist = tylist->tail ) { A_namety tydec = tylist->head; A_ty ty = tydec->ty; switch( ty->kind ) { case A_nameTy: { Ty_ty tyy = S_look( tenv , ty->u.name ); if( tyy->u.name.ty == NULL ) tyy->u.name.ty = dfsTypeDec( ty->pos , tenv , tyy->u.name.sym , tydec->name ); } case A_recordTy: case A_arrayTy: default: assert(0); } } } default: assert(0); } }