Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -175,20 +175,11 @@ private void compileStatement(AST.Stmt statement) {
}

private void compileAssign(AST.AssignStmt assignStmt) {
boolean indexedLhs = false;
if (!(assignStmt.lhs instanceof AST.NameExpr))
indexedLhs = compileExpr(assignStmt.lhs);
boolean indexedRhs = compileExpr(assignStmt.rhs);
if (indexedRhs)
codeIndexedLoad();
if (indexedLhs)
codeIndexedStore();
else if (assignStmt.lhs instanceof AST.NameExpr symbolExpr) {
Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) symbolExpr.symbol;
codeMove(pop(), new Operand.LocalRegisterOperand(registerPool.getReg(varSymbol.regNumber), varSymbol));
}
else
throw new CompilerException("Invalid assignment expression: " + assignStmt.lhs);
Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) assignStmt.nameExpr.symbol;
codeMove(pop(), new Operand.LocalRegisterOperand(registerPool.getReg(varSymbol.regNumber), varSymbol));
}

private void compileExprStmt(AST.ExprStmt exprStmt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,13 @@ else if (cbrInst.condition() instanceof Operand.ConstantOperand constantOperand)
int reg = baseReg;
for (Operand arg: callInst.args()) {
if (arg instanceof Operand.RegisterOperand param) {
execStack.stack[base + reg] = execStack.stack[base + param.frameSlot()];
execStack.stack[reg] = execStack.stack[base + param.frameSlot()];
}
else if (arg instanceof Operand.ConstantOperand constantOperand) {
execStack.stack[base + reg] = new Value.IntegerValue(constantOperand.value);
execStack.stack[reg] = new Value.IntegerValue(constantOperand.value);
}
else if (arg instanceof Operand.NullConstantOperand) {
execStack.stack[base + reg] = new Value.NullValue();
execStack.stack[reg] = new Value.NullValue();
}
reg += 1;
}
Expand Down Expand Up @@ -193,7 +193,7 @@ else if (binaryInst.right() instanceof Operand.RegisterOperand registerOperand)
case "<": value = x < y ? 1: 0; break;
case ">": value = x > y ? 1 : 0; break;
case "<=": value = x <= y ? 1 : 0; break;
case ">=": value = x <= y ? 1 : 0; break;
case ">=": value = x >= y ? 1 : 0; break;
default: throw new IllegalStateException();
}
execStack.stack[base + binaryInst.result().frameSlot()] = new Value.IntegerValue(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -731,16 +731,17 @@ public void accept(ASTVisitor visitor) {
}
}

/* name = value */
public static class AssignStmt extends Stmt {
public final Expr lhs;
public final NameExpr nameExpr;
public final Expr rhs;
public AssignStmt(Expr lhs, Expr rhs) {
this.lhs = lhs;
public AssignStmt(NameExpr nameExpr, Expr rhs) {
this.nameExpr = nameExpr;
this.rhs = rhs;
}
@Override
public StringBuilder toStr(StringBuilder sb) {
lhs.toStr(sb);
nameExpr.toStr(sb);
sb.append(" = ");
rhs.toStr(sb);
return sb;
Expand All @@ -751,7 +752,7 @@ public void accept(ASTVisitor visitor) {
visitor = visitor.visit(this, true);
if (visitor == null)
return;
lhs.accept(visitor);
nameExpr.accept(visitor);
rhs.accept(visitor);
visitor.visit(this, false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,11 @@ private AST.Stmt parseAssign(Lexer lexer) {
else if (lhs instanceof AST.GetFieldExpr getFieldExpr) {
return new AST.ExprStmt(new AST.SetFieldExpr(getFieldExpr.object, getFieldExpr.fieldName, rhs));
}
else if (lhs instanceof AST.NameExpr nameExpr) {
return new AST.AssignStmt(nameExpr, rhs);
}
else throw new CompilerException("Expected a name, expr[] or expr.field");
}
return new AST.AssignStmt(lhs, rhs);
}

private AST.Expr parseBool(Lexer lexer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,11 @@ private void compileStatement(AST.Stmt statement) {
}

private void compileAssign(AST.AssignStmt assignStmt) {
boolean indexedLhs = false;
if (!(assignStmt.lhs instanceof AST.NameExpr))
indexedLhs = compileExpr(assignStmt.lhs);
boolean indexedRhs = compileExpr(assignStmt.rhs);
if (indexedRhs)
codeIndexedLoad();
if (indexedLhs)
codeIndexedStore();
else if (assignStmt.lhs instanceof AST.NameExpr symbolExpr) {
Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) symbolExpr.symbol;
code(new Instruction.Move(pop(), new Operand.LocalRegisterOperand(varSymbol.regNumber, varSymbol.name)));
}
else
throw new CompilerException("Invalid assignment expression: " + assignStmt.lhs);
Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) assignStmt.nameExpr.symbol;
code(new Instruction.Move(pop(), new Operand.LocalRegisterOperand(varSymbol.regNumber, varSymbol.name)));
}

private void compileExprStmt(AST.ExprStmt exprStmt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,13 @@ else if (cbrInst.condition() instanceof Operand.ConstantOperand constantOperand)
int reg = baseReg;
for (Operand arg: callInst.args()) {
if (arg instanceof Operand.RegisterOperand param) {
execStack.stack[base + reg] = execStack.stack[base + param.frameSlot()];
execStack.stack[reg] = execStack.stack[base + param.frameSlot()];
}
else if (arg instanceof Operand.ConstantOperand constantOperand) {
execStack.stack[base + reg] = new Value.IntegerValue(constantOperand.value);
execStack.stack[reg] = new Value.IntegerValue(constantOperand.value);
}
else if (arg instanceof Operand.NullConstantOperand) {
execStack.stack[base + reg] = new Value.NullValue();
execStack.stack[reg] = new Value.NullValue();
}
reg += 1;
}
Expand Down Expand Up @@ -193,7 +193,7 @@ else if (binaryInst.right() instanceof Operand.RegisterOperand registerOperand)
case "<": value = x < y ? 1: 0; break;
case ">": value = x > y ? 1 : 0; break;
case "<=": value = x <= y ? 1 : 0; break;
case ">=": value = x <= y ? 1 : 0; break;
case ">=": value = x >= y ? 1 : 0; break;
default: throw new IllegalStateException();
}
execStack.stack[base + binaryInst.result().frameSlot()] = new Value.IntegerValue(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,4 +244,92 @@ func foo()->Int
Assert.assertTrue(value instanceof Value.IntegerValue integerValue &&
integerValue.value == 1);
}

@Test
public void testMergeSort() {
String src = """
// based on the top-down version from https://en.wikipedia.org/wiki/Merge_sort
// via https://github.com/SeaOfNodes/Simple
func merge_sort(a: [Int], b: [int], n: Int)
{
copy_array(a, 0, n, b)
split_merge(a, 0, n, b)
}

func split_merge(b: [Int], begin: Int, end: Int, a: [Int])
{
if (end - begin <= 1)
return;
var middle = (end + begin) / 2
split_merge(a, begin, middle, b)
split_merge(a, middle, end, b)
merge(b, begin, middle, end, a)
}

func merge(b: [Int], begin: Int, middle: Int, end: Int, a: [Int])
{
var i = begin
var j = middle
var k = begin
while (k < end) {
// && and ||
var cond = 0
if (i < middle) {
if (j >= end) cond = 1;
else if (a[i] <= a[j]) cond = 1;
}
if (cond)
{
b[k] = a[i]
i = i + 1
}
else
{
b[k] = a[j]
j = j + 1
}
k = k + 1
}
}

func copy_array(a: [Int], begin: Int, end: Int, b: [Int])
{
var k = begin
while (k < end)
{
b[k] = a[k]
k = k + 1
}
}

func eq(a: [Int], b: [Int], n: Int)->Int
{
var result = 1
var i = 0
while (i < n)
{
if (a[i] != b[i])
{
result = 0
break
}
i = i + 1
}
return result
}

func main()->Int
{
var a = new [Int]{10,9,8,7,6,5,4,3,2,1}
var b = new [Int]{ 0,0,0,0,0,0,0,0,0,0}
var expect = new [Int]{1,2,3,4,5,6,7,8,9,10}
merge_sort(a, b, 10)
return eq(a,expect,10)
}
""";
var value = compileAndRun(src, "main");
Assert.assertNotNull(value);
Assert.assertTrue(value instanceof Value.IntegerValue integerValue &&
integerValue.value == 1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,9 @@ private Node compileStatement(AST.Stmt statement) {
case AST.VarStmt letStmt -> {
return compileLet(letStmt);
}
case AST.VarDeclStmt varDeclStmt -> {}
case AST.VarDeclStmt varDeclStmt -> {
return ZERO;
}
case AST.IfElseStmt ifElseStmt -> {
return compileIf(ifElseStmt);
}
Expand All @@ -736,7 +738,6 @@ private Node compileStatement(AST.Stmt statement) {
}
default -> throw new IllegalStateException("Unexpected value: " + statement);
}
throw new CompilerException("Not yet implemented");
}

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

// At exit the false control is the current control, and
// the scope is the exit scope after the exit test.
_xScopes.pop();
_xScopes.push(exit);
_scope = exit;
return ZERO;
}

private Node compileIf(AST.IfElseStmt ifElseStmt) {
var pred = compileExpr(ifElseStmt.condition).keep();
pred.keep();

// IfNode takes current control and predicate
Node ifNode = new IfNode(ctrl(), pred).peephole();
// Setup projection nodes
Expand Down Expand Up @@ -914,8 +912,7 @@ private Node compileExprStmt(AST.ExprStmt exprStmt) {
}

private Node compileAssign(AST.AssignStmt assignStmt) {
if (!(assignStmt.lhs instanceof AST.NameExpr nameExpr))
throw new CompilerException("Assignment requires a nameExpr");
var nameExpr = assignStmt.nameExpr;
String name = nameExpr.name;
if (!(nameExpr.symbol instanceof Symbol.VarSymbol varSymbol))
throw new CompilerException("Assignment requires a variable name");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import java.util.stream.Collectors;

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

static final int DUMP_AFTER_PARSE = 1<<0;
static final int DUMP_AFTER_OPTO = 1<<1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,9 @@ public ASTVisitor visit(AST.ExprStmt exprStmt, boolean enter) {
@Override
public ASTVisitor visit(AST.AssignStmt assignStmt, boolean enter) {
if (!enter) {
validType(assignStmt.lhs.type, false);
validType(assignStmt.nameExpr.type, false);
validType(assignStmt.rhs.type, true);
checkAssignmentCompatible(assignStmt.lhs.type, assignStmt.rhs.type);
checkAssignmentCompatible(assignStmt.nameExpr.type, assignStmt.rhs.type);
}
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.compilerprogramming.ezlang.parser.Parser;
import com.compilerprogramming.ezlang.types.TypeDictionary;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;

public class TestSemaAssignTypes {
Expand Down Expand Up @@ -420,4 +421,20 @@ func foo()
""";
analyze(src, "foo", "func foo()");
}

@Ignore
@Test(expected = CompilerException.class)
public void test23() {
String src = """
func bar(arg: Int)->Int {
if (arg)
return 42;
return 0;
}
func foo()->Int {
return bar();
}
""";
analyze(src, "foo", "func foo()->Int");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,11 @@ private void compileStatement(AST.Stmt statement) {
}

private void compileAssign(AST.AssignStmt assignStmt) {
boolean indexedLhs = false;
if (!(assignStmt.lhs instanceof AST.NameExpr))
indexedLhs = compileExpr(assignStmt.lhs);
boolean indexedRhs = compileExpr(assignStmt.rhs);
if (indexedRhs)
codeIndexedLoad();
if (indexedLhs)
codeIndexedStore();
else if (assignStmt.lhs instanceof AST.NameExpr symbolExpr) {
Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) symbolExpr.symbol;
code(new Instruction.Store(varSymbol.regNumber));
}
else
throw new CompilerException("Invalid assignment expression: " + assignStmt.lhs);
Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) assignStmt.nameExpr.symbol;
code(new Instruction.Store(varSymbol.regNumber));
}

private void compileExprStmt(AST.ExprStmt exprStmt) {
Expand Down