Skip to content

Update SON backend to match chapter 22 of Simple #56

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 9, 2025
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 @@ -4,7 +4,7 @@
import com.compilerprogramming.ezlang.parser.AST;
import com.compilerprogramming.ezlang.types.Scope;
import com.compilerprogramming.ezlang.types.Symbol;
import com.compilerprogramming.ezlang.types.Type;
import com.compilerprogramming.ezlang.types.EZType;
import com.compilerprogramming.ezlang.types.TypeDictionary;

import java.util.*;
Expand All @@ -17,7 +17,7 @@ public class CompiledFunction {
public BasicBlock currentBlock;
private BasicBlock currentBreakTarget;
private BasicBlock currentContinueTarget;
public Type.TypeFunction functionType;
public EZType.EZTypeFunction functionType;
public final RegisterPool registerPool;
private final TypeDictionary typeDictionary;

Expand All @@ -39,7 +39,7 @@ public class CompiledFunction {

public CompiledFunction(Symbol.FunctionTypeSymbol functionSymbol, TypeDictionary typeDictionary, EnumSet<Options> options) {
AST.FuncDecl funcDecl = (AST.FuncDecl) functionSymbol.functionDecl;
this.functionType = (Type.TypeFunction) functionSymbol.type;
this.functionType = (EZType.EZTypeFunction) functionSymbol.type;
this.registerPool = new RegisterPool();
// Incremental SSA is an optional feature
this.issa = (options != null && options.contains(Options.ISSA)) ? new IncrementalSSABraun(this) : new NoopIncrementalSSA();
Expand All @@ -60,8 +60,8 @@ public CompiledFunction(Symbol.FunctionTypeSymbol functionSymbol, TypeDictionary
public CompiledFunction(Symbol.FunctionTypeSymbol functionSymbol, TypeDictionary typeDictionary) {
this(functionSymbol,typeDictionary,null);
}
public CompiledFunction(Type.TypeFunction functionType, TypeDictionary typeDictionary) {
this.functionType = (Type.TypeFunction) functionType;
public CompiledFunction(EZType.EZTypeFunction functionType, TypeDictionary typeDictionary) {
this.functionType = (EZType.EZTypeFunction) functionType;
this.registerPool = new RegisterPool();
this.issa = new NoopIncrementalSSA(); this.BID = 0;
this.entry = this.currentBlock = createBlock();
Expand Down Expand Up @@ -325,7 +325,7 @@ private boolean compileExpr(AST.Expr expr) {
private boolean compileCallExpr(AST.CallExpr callExpr) {
compileExpr(callExpr.callee);
var callee = pop();
Type.TypeFunction calleeType = null;
EZType.EZTypeFunction calleeType = null;
if (callee instanceof Operand.LocalFunctionOperand functionOperand)
calleeType = functionOperand.functionType;
else throw new CompilerException("Cannot call a non function type");
Expand All @@ -347,28 +347,28 @@ private boolean compileCallExpr(AST.CallExpr callExpr) {
for (int i = 0; i < args.size(); i++)
pop();
Operand.TempRegisterOperand ret = null;
if (callExpr.callee.type instanceof Type.TypeFunction tf &&
!(tf.returnType instanceof Type.TypeVoid)) {
if (callExpr.callee.type instanceof EZType.EZTypeFunction tf &&
!(tf.returnType instanceof EZType.EZTypeVoid)) {
ret = createTemp(tf.returnType);
}
codeCall(returnStackPos, ret, calleeType, args.toArray(new Operand.RegisterOperand[args.size()]));
return false;
}

private Type.TypeStruct getStructType(Type t) {
if (t instanceof Type.TypeStruct typeStruct) {
private EZType.EZTypeStruct getStructType(EZType t) {
if (t instanceof EZType.EZTypeStruct typeStruct) {
return typeStruct;
}
else if (t instanceof Type.TypeNullable ptr &&
ptr.baseType instanceof Type.TypeStruct typeStruct) {
else if (t instanceof EZType.EZTypeNullable ptr &&
ptr.baseType instanceof EZType.EZTypeStruct typeStruct) {
return typeStruct;
}
else
throw new CompilerException("Unexpected type: " + t);
}

private boolean compileFieldExpr(AST.GetFieldExpr fieldExpr) {
Type.TypeStruct typeStruct = getStructType(fieldExpr.object.type);
EZType.EZTypeStruct typeStruct = getStructType(fieldExpr.object.type);
int fieldIndex = typeStruct.getFieldIndex(fieldExpr.fieldName);
if (fieldIndex < 0)
throw new CompilerException("Field " + fieldExpr.fieldName + " not found");
Expand All @@ -391,7 +391,7 @@ private boolean compileArrayIndexExpr(AST.ArrayLoadExpr arrayIndexExpr) {
}

private boolean compileSetFieldExpr(AST.SetFieldExpr setFieldExpr) {
Type.TypeStruct structType = (Type.TypeStruct) setFieldExpr.object.type;
EZType.EZTypeStruct structType = (EZType.EZTypeStruct) setFieldExpr.object.type;
int fieldIndex = structType.getFieldIndex(setFieldExpr.fieldName);
if (fieldIndex == -1)
throw new CompilerException("Field " + setFieldExpr.fieldName + " not found in struct " + structType.name);
Expand Down Expand Up @@ -441,7 +441,7 @@ private boolean compileInitExpr(AST.InitExpr initExpr) {
}

private boolean compileSymbolExpr(AST.NameExpr symbolExpr) {
if (symbolExpr.type instanceof Type.TypeFunction functionType)
if (symbolExpr.type instanceof EZType.EZTypeFunction functionType)
pushOperand(new Operand.LocalFunctionOperand(functionType));
else {
Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) symbolExpr.symbol;
Expand Down Expand Up @@ -549,29 +549,29 @@ private boolean compileUnaryExpr(AST.UnaryExpr unaryExpr) {
}

private boolean compileConstantExpr(AST.LiteralExpr constantExpr) {
if (constantExpr.type instanceof Type.TypeInteger)
if (constantExpr.type instanceof EZType.EZTypeInteger)
pushConstant(constantExpr.value.num.intValue(), constantExpr.type);
else if (constantExpr.type instanceof Type.TypeNull)
else if (constantExpr.type instanceof EZType.EZTypeNull)
pushNullConstant(constantExpr.type);
else throw new CompilerException("Invalid constant type");
return false;
}

private void pushConstant(long value, Type type) {
private void pushConstant(long value, EZType type) {
pushOperand(new Operand.ConstantOperand(value, type));
}

private void pushNullConstant(Type type) {
private void pushNullConstant(EZType type) {
pushOperand(new Operand.NullConstantOperand(type));
}

private Operand.TempRegisterOperand createTemp(Type type) {
private Operand.TempRegisterOperand createTemp(EZType type) {
var tempRegister = new Operand.TempRegisterOperand(registerPool.newTempReg(type));
pushOperand(tempRegister);
return tempRegister;
}

Type typeOfOperand(Operand operand) {
EZType typeOfOperand(Operand operand) {
if (operand instanceof Operand.ConstantOperand constant)
return constant.type;
else if (operand instanceof Operand.NullConstantOperand nullConstantOperand)
Expand All @@ -582,7 +582,7 @@ else if (operand instanceof Operand.RegisterOperand registerOperand)
}

private Operand.TempRegisterOperand createTempAndMove(Operand src) {
Type type = typeOfOperand(src);
EZType type = typeOfOperand(src);
var temp = createTemp(type);
codeMove(src, temp);
return temp;
Expand Down Expand Up @@ -644,16 +644,16 @@ else if (indexed instanceof Operand.LoadFieldOperand loadFieldOperand)
codeMove(value, indexed);
}

private void codeNew(Type type, AST.Expr len, AST.Expr initVal) {
if (type instanceof Type.TypeArray typeArray)
private void codeNew(EZType type, AST.Expr len, AST.Expr initVal) {
if (type instanceof EZType.EZTypeArray typeArray)
codeNewArray(typeArray, len, initVal);
else if (type instanceof Type.TypeStruct typeStruct)
else if (type instanceof EZType.EZTypeStruct typeStruct)
codeNewStruct(typeStruct);
else
throw new CompilerException("Unexpected type: " + type);
}

private void codeNewArray(Type.TypeArray typeArray, AST.Expr len, AST.Expr initVal) {
private void codeNewArray(EZType.EZTypeArray typeArray, AST.Expr len, AST.Expr initVal) {
var temp = createTemp(typeArray);
Operand lenOperand = null;
Operand initValOperand = null;
Expand Down Expand Up @@ -685,7 +685,7 @@ private void codeNewArray(Type.TypeArray typeArray, AST.Expr len, AST.Expr initV
code(insn);
}

private void codeNewStruct(Type.TypeStruct typeStruct) {
private void codeNewStruct(EZType.EZTypeStruct typeStruct) {
var temp = createTemp(typeStruct);
var target = (Operand.RegisterOperand) issa.write(temp);
var insn = new Instruction.NewStruct(typeStruct, target);
Expand Down Expand Up @@ -729,7 +729,7 @@ private void codeCBR(BasicBlock block, Operand condition, BasicBlock trueBlock,

private void codeCall(int newBase,
Operand.RegisterOperand targetOperand,
Type.TypeFunction calleeType,
EZType.EZTypeFunction calleeType,
Operand.RegisterOperand ...arguments) {
if (targetOperand != null)
targetOperand = (Operand.RegisterOperand) issa.write(targetOperand);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.compilerprogramming.ezlang.semantic.SemaAssignTypes;
import com.compilerprogramming.ezlang.semantic.SemaDefineTypes;
import com.compilerprogramming.ezlang.types.Symbol;
import com.compilerprogramming.ezlang.types.Type;
import com.compilerprogramming.ezlang.types.EZType;
import com.compilerprogramming.ezlang.types.TypeDictionary;

import java.util.EnumSet;
Expand All @@ -15,7 +15,7 @@ public class Compiler {
private void compile(TypeDictionary typeDictionary, EnumSet<Options> options) {
for (Symbol symbol: typeDictionary.getLocalSymbols()) {
if (symbol instanceof Symbol.FunctionTypeSymbol functionSymbol) {
Type.TypeFunction functionType = (Type.TypeFunction) functionSymbol.type;
EZType.EZTypeFunction functionType = (EZType.EZTypeFunction) functionSymbol.type;
var function = new CompiledFunction(functionSymbol, typeDictionary, options);
if (options.contains(Options.DUMP_INITIAL_IR))
function.dumpIR(false, "Initial IR");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.exceptions.CompilerException;
import com.compilerprogramming.ezlang.types.Type;
import com.compilerprogramming.ezlang.types.EZType;

import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -139,16 +139,16 @@ public StringBuilder toStr(StringBuilder sb) {
}

public static class NewArray extends Instruction {
public final Type.TypeArray type;
public NewArray(Type.TypeArray type, Operand.RegisterOperand destOperand) {
public final EZType.EZTypeArray type;
public NewArray(EZType.EZTypeArray type, Operand.RegisterOperand destOperand) {
super(I_NEW_ARRAY, destOperand);
this.type = type;
}
public NewArray(Type.TypeArray type, Operand.RegisterOperand destOperand, Operand len) {
public NewArray(EZType.EZTypeArray type, Operand.RegisterOperand destOperand, Operand len) {
super(I_NEW_ARRAY, destOperand, len);
this.type = type;
}
public NewArray(Type.TypeArray type, Operand.RegisterOperand destOperand, Operand len, Operand initValue) {
public NewArray(EZType.EZTypeArray type, Operand.RegisterOperand destOperand, Operand len, Operand initValue) {
super(I_NEW_ARRAY, destOperand, len, initValue);
this.type = type;
}
Expand All @@ -170,8 +170,8 @@ public StringBuilder toStr(StringBuilder sb) {
}

public static class NewStruct extends Instruction {
public final Type.TypeStruct type;
public NewStruct(Type.TypeStruct type, Operand.RegisterOperand destOperand) {
public final EZType.EZTypeStruct type;
public NewStruct(EZType.EZTypeStruct type, Operand.RegisterOperand destOperand) {
super(I_NEW_STRUCT, destOperand);
this.type = type;
}
Expand Down Expand Up @@ -324,9 +324,9 @@ public StringBuilder toStr(StringBuilder sb) {
}

public static class Call extends Instruction {
public final Type.TypeFunction callee;
public final EZType.EZTypeFunction callee;
public final int newbase;
public Call(int newbase, Operand.RegisterOperand returnOperand, Type.TypeFunction callee, Operand.RegisterOperand... args) {
public Call(int newbase, Operand.RegisterOperand returnOperand, EZType.EZTypeFunction callee, Operand.RegisterOperand... args) {
super(I_CALL, returnOperand, args);
this.callee = callee;
this.newbase = newbase;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.types.Symbol;
import com.compilerprogramming.ezlang.types.Type;
import com.compilerprogramming.ezlang.types.EZType;

public class Operand {

Type type;
EZType type;

public static class ConstantOperand extends Operand {
public final long value;
public ConstantOperand(long value, Type type) {
public ConstantOperand(long value, EZType type) {
this.value = value;
this.type = type;
}
Expand All @@ -20,7 +20,7 @@ public String toString() {
}

public static class NullConstantOperand extends Operand {
public NullConstantOperand(Type type) {
public NullConstantOperand(EZType type) {
this.type = type;
}
@Override
Expand Down Expand Up @@ -61,8 +61,8 @@ public RegisterOperand copy(Register register) {
}

public static class LocalFunctionOperand extends Operand {
public final Type.TypeFunction functionType;
public LocalFunctionOperand(Type.TypeFunction functionType) {
public final EZType.EZTypeFunction functionType;
public LocalFunctionOperand(EZType.EZTypeFunction functionType) {
this.functionType = functionType;
}
@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.types.Type;
import com.compilerprogramming.ezlang.types.EZType;

/**
* Represents a Virtual Register in the abstract machine.
Expand Down Expand Up @@ -44,18 +44,18 @@ public class Register {
/**
* The type of the register
*/
public final Type type;
public final EZType type;
/**
* The location of this register relative to the base
* of the executing function. Multiple registers may share the same
* frame slot because of different non-overlapping life times.
*/
protected int frameSlot;

public Register(int id, String name, Type type) {
public Register(int id, String name, EZType type) {
this(id,name,type,id); // Initially frame slot is set to the unique ID
}
protected Register(int id, String name, Type type, int frameSlot) {
protected Register(int id, String name, EZType type, int frameSlot) {
this.id = id;
this.name = name;
this.type = type;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.types.Type;
import com.compilerprogramming.ezlang.types.EZType;

import java.util.ArrayList;

Expand All @@ -18,20 +18,20 @@ public class RegisterPool {
public Register getReg(int regNumber) {
return registers.get(regNumber);
}
public Register newReg(String baseName, Type type) {
public Register newReg(String baseName, EZType type) {
var id = registers.size();
var reg = new Register(id, baseName, type);
registers.add(reg);
return reg;
}
public Register newTempReg(Type type) {
public Register newTempReg(EZType type) {
var id = registers.size();
var name = "%t"+id;
var reg = new Register(id, name, type);
registers.add(reg);
return reg;
}
public Register newTempReg(String baseName, Type type) {
public Register newTempReg(String baseName, EZType type) {
var id = registers.size();
var name = baseName+"_"+id;
var reg = new Register(id, name, type);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.exceptions.CompilerException;
import com.compilerprogramming.ezlang.types.Type;
import com.compilerprogramming.ezlang.types.EZType;

import java.util.*;

Expand Down Expand Up @@ -361,7 +361,7 @@ private boolean evalInstruction(Instruction instruction) {
} else throw new IllegalStateException();
}
case Instruction.Call callInst -> {
if (!(callInst.callee.returnType instanceof Type.TypeVoid)) {
if (!(callInst.callee.returnType instanceof EZType.EZTypeVoid)) {
var cell = valueLattice.get(callInst.returnOperand().reg);
changed = cell.setKind(V_VARYING);
}
Expand Down
Loading