Permalink
Browse files

Support recursion, add tests, support redeclaration of globals in inn…

…er scopes
  • Loading branch information...
1 parent f0e859d commit 5c7009a019880ca2bfefcd22dcbd66c2e9d4114a @markflorisson committed Jul 5, 2011
View
Binary file not shown.
View
@@ -108,7 +108,7 @@ declaration
break;
}
}
- | ^(FUNCDEF funcname=ID
+ | ^(node=FUNCDEF funcname=ID
{
//enter as void
if (st.funclevel != 0)
@@ -122,12 +122,13 @@ declaration
}
)*
(
- ^(node=FUNCRETURN type compoundexpression expression
+ ^(node=FUNCRETURN type
{
SELMATree type = (SELMATree) node.getChild(0);
- SELMATree expr = (SELMATree) node.getChild(2);
- st.retrieve($funcname).type = expr.SR_type;
-
+ st.retrieve($funcname).type = type.getSelmaType();
+ } compoundexpression expression
+ {
+ SELMATree expr = (SELMATree) node.getChild(2);
matchType(type, expr.SR_type);
})
| (compoundexpression))
View
@@ -55,14 +55,14 @@ options {
stack.push(o);
- st.openScope();
+ st.enterFuncScope();
curStackDepth = maxStackDepth = labelNum = st.localCount = 0;
st.nextAddr = 0;
}
private void leaveFuncScope() {
StackDepthLabelCounter o = stack.pop();
- st.closeScope();
+ st.leaveFuncScope();
curStackDepth = o.curStackDepth;
maxStackDepth = o.maxStackDepth;
labelNum = o.labelNum;
@@ -83,14 +83,13 @@ program
: ^(node=BEGIN {st.openScope();} compoundexpression END)
{ SELMATree expr = (SELMATree) $node.getChild(0);
int localsCount = st.getLocalsCount();
- List<String> globalVariableFields = st.getAllLocalVariablesWithTypes();
st.closeScope();
}
-> program(instructions={$compoundexpression.st},
source_file={SELMA.inputFilename},
stack_limit={maxStackDepth + 3}, // +3 for print
locals_limit={localsCount + 1}, // +1 for the String[] argv parameter
- fields={globalVariableFields},
+ fields={st.globals},
pop={expr.SR_type != SR_Type.VOID})
;
@@ -135,42 +134,46 @@ declaration
enterFuncScope();
int paramCount = 0;
StringBuilder signatureBuilder = new StringBuilder("(");
- //List<String> paramTypeDenoters = new ArrayList<String>();
+ boolean hasReturnType = false;
} (param=ID typ1=(INT|BOOL|CHAR)
{
SELMATree type1 = (SELMATree) $node.getChild(++paramCount * 2);
signatureBuilder.append(getTypeDenoter(type1.getSelmaType()));
//paramTypeDenoters.add(getTypeDenoter(type1.getSelmaType()));
st.addParamToFunc($funcname, param, type1);
})*
- ( ^(return_node=FUNCRETURN (INT|BOOL|CHAR) (body+=compoundexpression) retexpr=expression)
- | (body+=compoundexpression)
+ ( ^(return_node=FUNCRETURN (INT|BOOL|CHAR)
+ {
+ SELMATree returnTypeNode = (SELMATree) $return_node.getChild(0);
+
+ signatureBuilder.append(")");
+ signatureBuilder.append(getTypeDenoter(returnTypeNode.getSelmaType()));
+ funcentry.signature = signatureBuilder.toString();
+
+ hasReturnType = true;
+ }
+
+ (body+=compoundexpression) retexpr=expression)
+ | ({funcentry.signature = signatureBuilder.toString() + ")V";} body+=compoundexpression)
)
{
- SELMATree funcbody;
+ SELMATree funcbody;
int stackLimit = maxStackDepth + 3;
int localsLimit = st.getLocalsCount();
-
- signatureBuilder.append(")");
-
- if ($return_node == null) {
- funcbody = (SELMATree) $node.getChild(paramCount * 2 + 1);
- signatureBuilder.append("V");
- } else {
+
+ if ($return_node == null)
+ funcbody = (SELMATree) $node.getChild(paramCount * 2 + 1);
+ else
funcbody = (SELMATree) $return_node.getChild(1);
- SELMATree returnType = (SELMATree) $return_node.getChild(0);
- signatureBuilder.append(getTypeDenoter(returnType.getSelmaType()));
- }
+
leaveFuncScope();
-
- String signature = signatureBuilder.toString();
- funcentry.signature = signature;
- })
+ }
+ )
-> function(funcname={$funcname.text},
body={$body},
- signature={signature},
+ signature={funcentry.signature},
return_expression={$retexpr.st},
- is_void={signature.endsWith("V")},
+ is_void={funcentry.signature.endsWith("V")},
pop={funcbody.SR_type != SR_Type.VOID},
stack_limit={stackLimit},
locals_limit={localsLimit + 1},
@@ -293,8 +296,8 @@ expression
addrs.add(entry.addr);
isBool.add(child.SR_type == SR_Type.BOOL);
isInt.add(child.SR_type == SR_Type.INT);
- globals.add(entry.level == 0);
- ids.add(child.getText());
+ globals.add(entry.isGlobal);
+ ids.add(entry.getIdentifier(child.getText()));
}
}
-> read(ids={ids}, addrs={addrs}, dup_top={isExpr},
@@ -337,19 +340,15 @@ expression
| ^(BECOMES node=ID e1=expression)
{
CompilerEntry entry = st.retrieve(node);
+ String ident = entry.getIdentifier($node.text);
boolean isConst = node.SR_kind == SR_Kind.CONST;
- boolean isGlobal = false;
String typeDenoter = getTypeDenoter(entry.type);
-
- if (entry.level == 0) {
- isGlobal = true;
- }
}
- -> assign(id={$node.text},
+ -> assign(id={ident},
type={$node.type},
addr={st.retrieve($node).addr},
e1={$e1.st},
- is_global={isGlobal},
+ is_global={entry.isGlobal},
type_denoter={typeDenoter})
//closedcompound
@@ -372,16 +371,12 @@ expression
{
incrStackDepth();
CompilerEntry entry = st.retrieve(node);
+ String ident = entry.getIdentifier($node.text);
boolean isConst = node.SR_kind == SR_Kind.CONST;
- boolean isGlobal = false;
String typeDenoter = getTypeDenoter(entry.type);
-
- if (entry.level == 0) {
- isGlobal = true;
- }
}
- -> loadVal(id={$node.text}, addr={entry.addr}, val={entry.val}, is_const={isConst},
- is_global={isGlobal}, type_denoter={typeDenoter})
+ -> loadVal(id={ident}, addr={entry.addr}, val={entry.val}, is_const={isConst},
+ is_global={entry.isGlobal}, type_denoter={typeDenoter})
;
View
@@ -47,12 +47,12 @@ if @checkjaar(jaar,); then
function nest(stap,w: integer;): integer {
var returnvalue: integer;
if stap==1; then
- returnvalue := 3*w;
+ returnvalue := 3*w;
else
if stap == 2; then
returnvalue := w/4;
var loop: integer;
- loop := 1;
+ loop := 1;
while loop <= twaalf; do
returnvalue := returnvalue-1;
loop := loop + 1;
@@ -72,15 +72,16 @@ if @checkjaar(jaar,); then
Y := (8*C)/25 - 5;
fi;
+ function copy(jaar: integer;): integer {
+ 42;
+ return jaar;
+ };
+
// Zoek de zondag:
// Vermenigvuldig het jaartal met 5, geheeldeel de uitkomst door 4, trek er X en 10 vanaf, en noem dit getal Z. Voor 1991 geldt: Z = 2475.
function nested(): integer {
var Z: integer;
Z := (((jaar*5)/4)-X)+-10;
- function copy(jaar: integer;): integer {
- 42;
- return jaar;
- };
Z := @copy(Z,);
return Z;
};
@@ -89,9 +90,9 @@ if @checkjaar(jaar,); then
// Bepaal de epacta:
// 11 maal G + 20 + Y. Trek daarvan X af, geheeldeel het resultaat door 30 en noem de rest E. Als E gelijk is aan 24, of als E gelijk is aan 25 en het gulden getal is groter dan 11, tel dan 1 bij E op. De Epacta voor 1991 is 14.
- var E,EE: integer;
+ var E,EE: integer;
E := EE := ({const elf: integer = 11; elf*(G+20+Y);}-X)/30;
- const mnope: boolean = false;
+ const mnope: boolean = false;
if EE==24 || (E==25&&G>11) || mnope; then
E := 1+E;
fi;
@@ -103,7 +104,7 @@ if @checkjaar(jaar,); then
N := minus2-E;
var tosmall: boolean;
tosmall := N<21;
- N := N+
+ N := N+
if tosmall; then
30;
else
@@ -117,7 +118,7 @@ if @checkjaar(jaar,); then
// Paasdatum: Als P groter is dan 31, trek er dan 31 vanaf, en de paasdatum valt in April. Anders is de paasdag P in Maart. Zo wordt voor 1991 gevonden 31 maart.
var month: integer;
- var day: integer;
+ var day: integer;
if P>31; then
month := 4;
day := P%31;
@@ -128,14 +129,14 @@ if @checkjaar(jaar,); then
function printdatum() {
print(day);
- var under: character;
+ var under: character;
under := print('_');
if month==3; then
print('M','a','a','r','t');
else
print('A','p','r','i','l');
fi;
- print(under,jaar);
+ print(under,jaar);
};
@printdatum();
fi;
Oops, something went wrong.

0 comments on commit 5c7009a

Please sign in to comment.