Skip to content

Commit 4f3a2ac

Browse files
Merge pull request #39 from CompilerProgramming/develop
Some fixes and refactoring
2 parents 956ed07 + fd1ae26 commit 4f3a2ac

File tree

12 files changed

+136
-57
lines changed

12 files changed

+136
-57
lines changed

optvm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -175,20 +175,11 @@ private void compileStatement(AST.Stmt statement) {
175175
}
176176

177177
private void compileAssign(AST.AssignStmt assignStmt) {
178-
boolean indexedLhs = false;
179-
if (!(assignStmt.lhs instanceof AST.NameExpr))
180-
indexedLhs = compileExpr(assignStmt.lhs);
181178
boolean indexedRhs = compileExpr(assignStmt.rhs);
182179
if (indexedRhs)
183180
codeIndexedLoad();
184-
if (indexedLhs)
185-
codeIndexedStore();
186-
else if (assignStmt.lhs instanceof AST.NameExpr symbolExpr) {
187-
Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) symbolExpr.symbol;
188-
codeMove(pop(), new Operand.LocalRegisterOperand(registerPool.getReg(varSymbol.regNumber), varSymbol));
189-
}
190-
else
191-
throw new CompilerException("Invalid assignment expression: " + assignStmt.lhs);
181+
Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) assignStmt.nameExpr.symbol;
182+
codeMove(pop(), new Operand.LocalRegisterOperand(registerPool.getReg(varSymbol.regNumber), varSymbol));
192183
}
193184

194185
private void compileExprStmt(AST.ExprStmt exprStmt) {

optvm/src/main/java/com/compilerprogramming/ezlang/interpreter/Interpreter.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,13 @@ else if (cbrInst.condition() instanceof Operand.ConstantOperand constantOperand)
108108
int reg = baseReg;
109109
for (Operand arg: callInst.args()) {
110110
if (arg instanceof Operand.RegisterOperand param) {
111-
execStack.stack[base + reg] = execStack.stack[base + param.frameSlot()];
111+
execStack.stack[reg] = execStack.stack[base + param.frameSlot()];
112112
}
113113
else if (arg instanceof Operand.ConstantOperand constantOperand) {
114-
execStack.stack[base + reg] = new Value.IntegerValue(constantOperand.value);
114+
execStack.stack[reg] = new Value.IntegerValue(constantOperand.value);
115115
}
116116
else if (arg instanceof Operand.NullConstantOperand) {
117-
execStack.stack[base + reg] = new Value.NullValue();
117+
execStack.stack[reg] = new Value.NullValue();
118118
}
119119
reg += 1;
120120
}
@@ -193,7 +193,7 @@ else if (binaryInst.right() instanceof Operand.RegisterOperand registerOperand)
193193
case "<": value = x < y ? 1: 0; break;
194194
case ">": value = x > y ? 1 : 0; break;
195195
case "<=": value = x <= y ? 1 : 0; break;
196-
case ">=": value = x <= y ? 1 : 0; break;
196+
case ">=": value = x >= y ? 1 : 0; break;
197197
default: throw new IllegalStateException();
198198
}
199199
execStack.stack[base + binaryInst.result().frameSlot()] = new Value.IntegerValue(value);

parser/src/main/java/com/compilerprogramming/ezlang/parser/AST.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -731,16 +731,17 @@ public void accept(ASTVisitor visitor) {
731731
}
732732
}
733733

734+
/* name = value */
734735
public static class AssignStmt extends Stmt {
735-
public final Expr lhs;
736+
public final NameExpr nameExpr;
736737
public final Expr rhs;
737-
public AssignStmt(Expr lhs, Expr rhs) {
738-
this.lhs = lhs;
738+
public AssignStmt(NameExpr nameExpr, Expr rhs) {
739+
this.nameExpr = nameExpr;
739740
this.rhs = rhs;
740741
}
741742
@Override
742743
public StringBuilder toStr(StringBuilder sb) {
743-
lhs.toStr(sb);
744+
nameExpr.toStr(sb);
744745
sb.append(" = ");
745746
rhs.toStr(sb);
746747
return sb;
@@ -751,7 +752,7 @@ public void accept(ASTVisitor visitor) {
751752
visitor = visitor.visit(this, true);
752753
if (visitor == null)
753754
return;
754-
lhs.accept(visitor);
755+
nameExpr.accept(visitor);
755756
rhs.accept(visitor);
756757
visitor.visit(this, false);
757758
}

parser/src/main/java/com/compilerprogramming/ezlang/parser/Parser.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,11 @@ private AST.Stmt parseAssign(Lexer lexer) {
253253
else if (lhs instanceof AST.GetFieldExpr getFieldExpr) {
254254
return new AST.ExprStmt(new AST.SetFieldExpr(getFieldExpr.object, getFieldExpr.fieldName, rhs));
255255
}
256+
else if (lhs instanceof AST.NameExpr nameExpr) {
257+
return new AST.AssignStmt(nameExpr, rhs);
258+
}
259+
else throw new CompilerException("Expected a name, expr[] or expr.field");
256260
}
257-
return new AST.AssignStmt(lhs, rhs);
258261
}
259262

260263
private AST.Expr parseBool(Lexer lexer) {

registervm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -139,20 +139,11 @@ private void compileStatement(AST.Stmt statement) {
139139
}
140140

141141
private void compileAssign(AST.AssignStmt assignStmt) {
142-
boolean indexedLhs = false;
143-
if (!(assignStmt.lhs instanceof AST.NameExpr))
144-
indexedLhs = compileExpr(assignStmt.lhs);
145142
boolean indexedRhs = compileExpr(assignStmt.rhs);
146143
if (indexedRhs)
147144
codeIndexedLoad();
148-
if (indexedLhs)
149-
codeIndexedStore();
150-
else if (assignStmt.lhs instanceof AST.NameExpr symbolExpr) {
151-
Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) symbolExpr.symbol;
152-
code(new Instruction.Move(pop(), new Operand.LocalRegisterOperand(varSymbol.regNumber, varSymbol.name)));
153-
}
154-
else
155-
throw new CompilerException("Invalid assignment expression: " + assignStmt.lhs);
145+
Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) assignStmt.nameExpr.symbol;
146+
code(new Instruction.Move(pop(), new Operand.LocalRegisterOperand(varSymbol.regNumber, varSymbol.name)));
156147
}
157148

158149
private void compileExprStmt(AST.ExprStmt exprStmt) {

registervm/src/main/java/com/compilerprogramming/ezlang/interpreter/Interpreter.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,13 @@ else if (cbrInst.condition() instanceof Operand.ConstantOperand constantOperand)
108108
int reg = baseReg;
109109
for (Operand arg: callInst.args()) {
110110
if (arg instanceof Operand.RegisterOperand param) {
111-
execStack.stack[base + reg] = execStack.stack[base + param.frameSlot()];
111+
execStack.stack[reg] = execStack.stack[base + param.frameSlot()];
112112
}
113113
else if (arg instanceof Operand.ConstantOperand constantOperand) {
114-
execStack.stack[base + reg] = new Value.IntegerValue(constantOperand.value);
114+
execStack.stack[reg] = new Value.IntegerValue(constantOperand.value);
115115
}
116116
else if (arg instanceof Operand.NullConstantOperand) {
117-
execStack.stack[base + reg] = new Value.NullValue();
117+
execStack.stack[reg] = new Value.NullValue();
118118
}
119119
reg += 1;
120120
}
@@ -193,7 +193,7 @@ else if (binaryInst.right() instanceof Operand.RegisterOperand registerOperand)
193193
case "<": value = x < y ? 1: 0; break;
194194
case ">": value = x > y ? 1 : 0; break;
195195
case "<=": value = x <= y ? 1 : 0; break;
196-
case ">=": value = x <= y ? 1 : 0; break;
196+
case ">=": value = x >= y ? 1 : 0; break;
197197
default: throw new IllegalStateException();
198198
}
199199
execStack.stack[base + binaryInst.result().frameSlot()] = new Value.IntegerValue(value);

registervm/src/test/java/com/compilerprogramming/ezlang/interpreter/TestInterpreter.java

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,92 @@ func foo()->Int
244244
Assert.assertTrue(value instanceof Value.IntegerValue integerValue &&
245245
integerValue.value == 1);
246246
}
247+
248+
@Test
249+
public void testMergeSort() {
250+
String src = """
251+
// based on the top-down version from https://en.wikipedia.org/wiki/Merge_sort
252+
// via https://github.com/SeaOfNodes/Simple
253+
func merge_sort(a: [Int], b: [int], n: Int)
254+
{
255+
copy_array(a, 0, n, b)
256+
split_merge(a, 0, n, b)
257+
}
258+
259+
func split_merge(b: [Int], begin: Int, end: Int, a: [Int])
260+
{
261+
if (end - begin <= 1)
262+
return;
263+
var middle = (end + begin) / 2
264+
split_merge(a, begin, middle, b)
265+
split_merge(a, middle, end, b)
266+
merge(b, begin, middle, end, a)
267+
}
268+
269+
func merge(b: [Int], begin: Int, middle: Int, end: Int, a: [Int])
270+
{
271+
var i = begin
272+
var j = middle
273+
var k = begin
274+
while (k < end) {
275+
// && and ||
276+
var cond = 0
277+
if (i < middle) {
278+
if (j >= end) cond = 1;
279+
else if (a[i] <= a[j]) cond = 1;
280+
}
281+
if (cond)
282+
{
283+
b[k] = a[i]
284+
i = i + 1
285+
}
286+
else
287+
{
288+
b[k] = a[j]
289+
j = j + 1
290+
}
291+
k = k + 1
292+
}
293+
}
294+
295+
func copy_array(a: [Int], begin: Int, end: Int, b: [Int])
296+
{
297+
var k = begin
298+
while (k < end)
299+
{
300+
b[k] = a[k]
301+
k = k + 1
302+
}
303+
}
304+
305+
func eq(a: [Int], b: [Int], n: Int)->Int
306+
{
307+
var result = 1
308+
var i = 0
309+
while (i < n)
310+
{
311+
if (a[i] != b[i])
312+
{
313+
result = 0
314+
break
315+
}
316+
i = i + 1
317+
}
318+
return result
319+
}
320+
321+
func main()->Int
322+
{
323+
var a = new [Int]{10,9,8,7,6,5,4,3,2,1}
324+
var b = new [Int]{ 0,0,0,0,0,0,0,0,0,0}
325+
var expect = new [Int]{1,2,3,4,5,6,7,8,9,10}
326+
merge_sort(a, b, 10)
327+
return eq(a,expect,10)
328+
}
329+
""";
330+
var value = compileAndRun(src, "main");
331+
Assert.assertNotNull(value);
332+
Assert.assertTrue(value instanceof Value.IntegerValue integerValue &&
333+
integerValue.value == 1);
334+
}
247335
}

seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/Compiler.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,9 @@ private Node compileStatement(AST.Stmt statement) {
712712
case AST.VarStmt letStmt -> {
713713
return compileLet(letStmt);
714714
}
715-
case AST.VarDeclStmt varDeclStmt -> {}
715+
case AST.VarDeclStmt varDeclStmt -> {
716+
return ZERO;
717+
}
716718
case AST.IfElseStmt ifElseStmt -> {
717719
return compileIf(ifElseStmt);
718720
}
@@ -736,7 +738,6 @@ private Node compileStatement(AST.Stmt statement) {
736738
}
737739
default -> throw new IllegalStateException("Unexpected value: " + statement);
738740
}
739-
throw new CompilerException("Not yet implemented");
740741
}
741742

742743
private ScopeNode jumpTo(ScopeNode toScope) {
@@ -847,16 +848,13 @@ private Node compileWhile(AST.WhileStmt whileStmt) {
847848

848849
// At exit the false control is the current control, and
849850
// the scope is the exit scope after the exit test.
850-
_xScopes.pop();
851851
_xScopes.push(exit);
852852
_scope = exit;
853853
return ZERO;
854854
}
855855

856856
private Node compileIf(AST.IfElseStmt ifElseStmt) {
857857
var pred = compileExpr(ifElseStmt.condition).keep();
858-
pred.keep();
859-
860858
// IfNode takes current control and predicate
861859
Node ifNode = new IfNode(ctrl(), pred).peephole();
862860
// Setup projection nodes
@@ -914,8 +912,7 @@ private Node compileExprStmt(AST.ExprStmt exprStmt) {
914912
}
915913

916914
private Node compileAssign(AST.AssignStmt assignStmt) {
917-
if (!(assignStmt.lhs instanceof AST.NameExpr nameExpr))
918-
throw new CompilerException("Assignment requires a nameExpr");
915+
var nameExpr = assignStmt.nameExpr;
919916
String name = nameExpr.name;
920917
if (!(nameExpr.symbol instanceof Symbol.VarSymbol varSymbol))
921918
throw new CompilerException("Assignment requires a variable name");

seaofnodes/src/test/java/com/compilerprogramming/ezlang/compiler/Simple.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import java.util.stream.Collectors;
1212

1313
public class Simple {
14-
public static final String PORTS = "com.seaofnodes.simple.node.cpus";
14+
public static final String PORTS = "com.compilerprogramming.ezlang.compiler.nodes.cpus";
1515

1616
static final int DUMP_AFTER_PARSE = 1<<0;
1717
static final int DUMP_AFTER_OPTO = 1<<1;

semantic/src/main/java/com/compilerprogramming/ezlang/semantic/SemaAssignTypes.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,9 +385,9 @@ public ASTVisitor visit(AST.ExprStmt exprStmt, boolean enter) {
385385
@Override
386386
public ASTVisitor visit(AST.AssignStmt assignStmt, boolean enter) {
387387
if (!enter) {
388-
validType(assignStmt.lhs.type, false);
388+
validType(assignStmt.nameExpr.type, false);
389389
validType(assignStmt.rhs.type, true);
390-
checkAssignmentCompatible(assignStmt.lhs.type, assignStmt.rhs.type);
390+
checkAssignmentCompatible(assignStmt.nameExpr.type, assignStmt.rhs.type);
391391
}
392392
return this;
393393
}

0 commit comments

Comments
 (0)