Skip to main content

module examples::calc::Checker

rascal-0.34.0
typepal-0.8.10

Usage

import examples::calc::Checker;

Source code

http://github.com/usethesource/typepal/src/examples/calc/Checker.rsc

Dependencies

import examples::calc::Syntax;
extend analysis::typepal::TypePal;

data AType

data AType  
= boolType()
| intType()
;

function prettyAType

str prettyAType(boolType()) = "bool";

str prettyAType(intType()) = "int";

function collect

void collect(current: (Decl) `var <Id name> = <Exp exp> ;`, Collector c){
c.define("<name>", variableId(), current, defType(exp));
collect(exp, c);
}

void collect(current: (Exp) `<Id name>`, Collector c){
c.use(name, {variableId()});
}

void collect(current: (Exp) `<Boolean boolean>`, Collector c){
c.fact(current, boolType());
}

void collect(current: (Exp) `<Integer integer>`, Collector c){
c.fact(current, intType());
}

void collect(current: (Exp) `( <Exp e> )`, Collector c){
c.fact(current, e);
collect(e, c);
}

void collect(current: (Exp) `<Exp e1> + <Exp e2>`, Collector c){
c.calculate("addition", current, [e1, e2],
AType (Solver s) {
switch(<s.getType(e1), s.getType(e2)>){
case <intType(), intType()>: return intType();
case <boolType(), boolType()>: return boolType();
default: {
s.report(error(current, "`+` not defined for %t and %t", e1, e2));
return intType();
}
}
});
collect(e1, e2, c);
}

void collect(current: (Exp) `<Exp e1> * <Exp e2>`, Collector c){
c.calculate("multiplication", current, [e1, e2],
AType (Solver s) {
switch(<s.getType(e1), s.getType(e2)>){
case <intType(), intType()>: return intType();
case <boolType(), boolType()>: return boolType();
default: {
s.report(error(current, "`*` not defined for %t and %t", e1, e2));
return intType();
}
}
});
collect(e1, e2, c);
}

void collect(current: (Exp) `if <Exp cond> then <Exp e1> else <Exp e2>`, Collector c){
c.calculate("if Exp", current, [cond, e1, e2],
AType(Solver s){
s.requireEqual(cond, boolType(),
error(cond, "Condition should be Boolean, found %t", cond));
s.requireEqual(e1, e2,
error(current, "Equal types required, found %t and %t", e1, e2));
return s.getType(e1);
});
collect(cond, e1, e2, c);
}