Skip to main content

module demo::lang::Pico::Typecheck

rascal-0.34.0

Usage

import demo::lang::Pico::Typecheck;

Dependencies

import Prelude;
import demo::lang::Pico::Abstract;
import demo::lang::Pico::Load;

alias TENV

tuple[ map[PicoId, TYPE] symbols, list[tuple[loc l, str msg]] errors]

function addError

TENV addError(TENV env, loc l, str msg) = env[errors = env.errors + <l, msg>];

function required

str required(TYPE t, str got) = "Required <getName(t)>, but got <got>";

str required(TYPE t1, TYPE t2) = required(t1, getName(t2));

function checkExp

Checking Expressions


TENV checkExp(exp:natCon(int N), TYPE req, TENV env) =
req := natural() ? env : addError(env, exp.src, required(req, "natural"));

TENV checkExp(exp:strCon(str S), TYPE req, TENV env) =
req := string() ? env : addError(env, exp.src, required(req, "string"));

TENV checkExp(exp:id(PicoId Id), TYPE req, TENV env) {
if(!env.symbols[Id]?)
return addError(env, exp.src, "Undeclared variable <Id>");
tpid = env.symbols[Id];
return req := tpid ? env : addError(env, exp.src, required(req, tpid));
}

TENV checkExp(exp:add(EXP E1, EXP E2), TYPE req, TENV env) =
natural() := req ? checkExp(E1, natural(), checkExp(E2, natural(), env))
: addError(env, exp.src, required(req, "natural"));

TENV checkExp(exp:sub(EXP E1, EXP E2), TYPE req, TENV env) =
natural() := req ? checkExp(E1, natural(), checkExp(E2, natural(), env))
: addError(env, exp.src, required(req, "natural"));

TENV checkExp(exp:conc(EXP E1, EXP E2), TYPE req, TENV env) =
string() := req ? checkExp(E1, string(), checkExp(E2, string(), env))
: addError(env, exp.src, required(req, "string"));

function checkStat

Check a statement


TENV checkStat(stat:asgStat(PicoId Id, EXP Exp), TENV env) {
if(!env.symbols[Id]?)
return addError(env, stat.src, "Undeclared variable <Id>");
tpid = env.symbols[Id];
return checkExp(Exp, tpid, env);
}

TENV checkStat(stat:ifElseStat(EXP Exp, ❶⓿
list[STATEMENT] Stats1,
list[STATEMENT] Stats2),
TENV env){
env0 = checkExp(Exp, natural(), env);
env1 = checkStats(Stats1, env0);
env2 = checkStats(Stats2, env1);
return env2;
}

TENV checkStat(stat:whileStat(EXP Exp,
list[STATEMENT] Stats1),
TENV env) {
env0 = checkExp(Exp, natural(), env);
env1 = checkStats(Stats1, env0);
return env1;
}

function checkStats

Check a list of statements


TENV checkStats(list[STATEMENT] Stats1, TENV env) { ❶❶
for(S <- Stats1){
env = checkStat(S, env);
}
return env;
}

function checkDecls

Check declarations


TENV checkDecls(list[DECL] Decls) = ❶❷
<( Id : tp | decl(PicoId Id, TYPE tp) <- Decls), []>;

function checkProgram

Check a Pico program


TENV checkProgram(program(list[DECL] Decls, list[STATEMENT] Series)) { ❶❸
return checkStats(Series, checkDecls(Decls));
}

list[tuple[loc l, str msg]] checkProgram(str txt) = checkProgram(load(txt)).errors;