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
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ The project is under development and subject to change. At this point in time, w

## How can you contribute?

Obviously firstly any contributions that improve the implementation and/or fix bugs are welcome. I am not keen on language extensions at this stage, but eventually
we will be extending the language to explore more advanced features.
The project is educational, with a focus on exploring various compiler algorithms and data structures.
Clarity and simplicity is preferred over a coding style that attempts to do micro optimizations.

I am also interested in creating implementations of this project in C++, Go, Rust, Swift, D, C, etc. If you are interested in working on such a
Contributions that improve the quality of the implementation, add test cases / documentation or fix bugs, are very welcome.
I am not keen on language extensions at this stage, but eventually we will be extending the language to explore more
advanced features.

I am also interested in porting this project to C++, Go, Rust, Swift, D, C, etc. If you are interested in working on such a
port please contact me via [Discussions](https://github.com/orgs/CompilerProgramming/discussions).

## Community Discussions
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.types.Register;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.exceptions.CompilerException;
import com.compilerprogramming.ezlang.parser.AST;
Expand All @@ -10,7 +10,7 @@
import java.util.ArrayList;
import java.util.List;

public class BytecodeFunction {
public class CompiledFunction {

public BasicBlock entry;
public BasicBlock exit;
Expand Down Expand Up @@ -41,7 +41,7 @@ public class BytecodeFunction {
*/
private List<Operand> virtualStack = new ArrayList<>();

public BytecodeFunction(Symbol.FunctionTypeSymbol functionSymbol) {
public CompiledFunction(Symbol.FunctionTypeSymbol functionSymbol) {
AST.FuncDecl funcDecl = (AST.FuncDecl) functionSymbol.functionDecl;
setVirtualRegisters(funcDecl.scope);
this.numLocalRegs = this.nextReg; // Before assigning temps
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.lexer.Lexer;
import com.compilerprogramming.ezlang.parser.Parser;
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.TypeDictionary;

import java.util.BitSet;

public class Compiler {

private void compile(TypeDictionary typeDictionary) {
for (Symbol symbol: typeDictionary.getLocalSymbols()) {
if (symbol instanceof Symbol.FunctionTypeSymbol functionSymbol) {
Type.TypeFunction functionType = (Type.TypeFunction) functionSymbol.type;
functionType.code = new CompiledFunction(functionSymbol);
}
}
}
public TypeDictionary compileSrc(String src) {
Parser parser = new Parser();
var program = parser.parse(new Lexer(src));
var typeDict = new TypeDictionary();
var sema = new SemaDefineTypes(typeDict);
sema.analyze(program);
var sema2 = new SemaAssignTypes(typeDict);
sema2.analyze(program);
compile(typeDict);
return typeDict;
}
public String dumpIR(TypeDictionary typeDictionary) {
StringBuilder sb = new StringBuilder();
for (Symbol s: typeDictionary.bindings.values()) {
if (s instanceof Symbol.FunctionTypeSymbol f) {
var functionBuilder = (CompiledFunction) f.code();
BasicBlock.toStr(sb, functionBuilder.entry, new BitSet());
}
}
return sb.toString();
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.compiler;

import java.util.ArrayList;
import java.util.Comparator;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.types.Register;
import com.compilerprogramming.ezlang.types.Type;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.compiler;

import java.util.*;
import java.util.stream.Collectors;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.compiler;

import java.util.*;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.types.Register;
import com.compilerprogramming.ezlang.types.Type;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.types.Register;

Expand All @@ -9,15 +9,15 @@
*/
public class SSATransform {

BytecodeFunction function;
CompiledFunction function;
DominatorTree domTree;
Register[] globals;
BBSet[] blockSets;
List<BasicBlock> blocks;
int[] counters;
VersionStack[] stacks;

public SSATransform(BytecodeFunction bytecodeFunction) {
public SSATransform(CompiledFunction bytecodeFunction) {
this.function = bytecodeFunction;
setupGlobals();
computeDomTreeAndDominanceFrontiers();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.compilerprogramming.ezlang.interpreter;

import com.compilerprogramming.ezlang.bytecode.BasicBlock;
import com.compilerprogramming.ezlang.bytecode.BytecodeFunction;
import com.compilerprogramming.ezlang.bytecode.Instruction;
import com.compilerprogramming.ezlang.bytecode.Operand;
import com.compilerprogramming.ezlang.compiler.BasicBlock;
import com.compilerprogramming.ezlang.compiler.CompiledFunction;
import com.compilerprogramming.ezlang.compiler.Instruction;
import com.compilerprogramming.ezlang.compiler.Operand;
import com.compilerprogramming.ezlang.exceptions.CompilerException;
import com.compilerprogramming.ezlang.exceptions.InterpreterException;
import com.compilerprogramming.ezlang.types.Symbol;
Expand Down Expand Up @@ -31,7 +31,7 @@ public Value run(String functionName) {
}

public Value interpret(ExecutionStack execStack, Frame frame) {
BytecodeFunction currentFunction = frame.bytecodeFunction;
CompiledFunction currentFunction = frame.bytecodeFunction;
BasicBlock currentBlock = currentFunction.entry;
int ip = -1;
int base = frame.base;
Expand Down Expand Up @@ -239,18 +239,18 @@ else if (setFieldInst.sourceOperand instanceof Operand.RegisterOperand registerO
static class Frame {
Frame caller;
int base;
BytecodeFunction bytecodeFunction;
CompiledFunction bytecodeFunction;

public Frame(Symbol.FunctionTypeSymbol functionSymbol) {
this.caller = null;
this.base = 0;
this.bytecodeFunction = (BytecodeFunction) functionSymbol.code();
this.bytecodeFunction = (CompiledFunction) functionSymbol.code();
}

Frame(Frame caller, int base, Type.TypeFunction functionType) {
this.caller = caller;
this.base = base;
this.bytecodeFunction = (BytecodeFunction) functionType.code;
this.bytecodeFunction = (CompiledFunction) functionType.code;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,14 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.lexer.Lexer;
import com.compilerprogramming.ezlang.parser.Parser;
import com.compilerprogramming.ezlang.semantic.SemaAssignTypes;
import com.compilerprogramming.ezlang.semantic.SemaDefineTypes;
import com.compilerprogramming.ezlang.types.Symbol;
import com.compilerprogramming.ezlang.types.TypeDictionary;
import org.junit.Assert;
import org.junit.Test;

import java.util.BitSet;

public class TestCompiler {

String compileSrc(String src) {
Parser parser = new Parser();
var program = parser.parse(new Lexer(src));
var typeDict = new TypeDictionary();
var sema = new SemaDefineTypes(typeDict);
sema.analyze(program);
var sema2 = new SemaAssignTypes(typeDict);
sema2.analyze(program);
var byteCodeCompiler = new BytecodeCompiler();
byteCodeCompiler.compile(typeDict);
StringBuilder sb = new StringBuilder();
for (Symbol s : typeDict.bindings.values()) {
if (s instanceof Symbol.FunctionTypeSymbol f) {
var functionBuilder = (BytecodeFunction) f.code();
BasicBlock.toStr(sb, functionBuilder.entry, new BitSet());
}
}
return sb.toString();
var compiler = new Compiler();
var typeDict = compiler.compileSrc(src);
return compiler.dumpIR(typeDict);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.compiler;

import org.junit.Assert;
import org.junit.Test;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.compiler;

import com.compilerprogramming.ezlang.lexer.Lexer;
import com.compilerprogramming.ezlang.parser.Parser;
import com.compilerprogramming.ezlang.semantic.SemaAssignTypes;
import com.compilerprogramming.ezlang.semantic.SemaDefineTypes;
import com.compilerprogramming.ezlang.types.Symbol;
import com.compilerprogramming.ezlang.types.TypeDictionary;
import org.junit.Assert;
import org.junit.Test;

Expand All @@ -14,19 +9,12 @@
public class TestSSATransform {

String compileSrc(String src) {
Parser parser = new Parser();
var program = parser.parse(new Lexer(src));
var typeDict = new TypeDictionary();
var sema = new SemaDefineTypes(typeDict);
sema.analyze(program);
var sema2 = new SemaAssignTypes(typeDict);
sema2.analyze(program);
var byteCodeCompiler = new BytecodeCompiler();
byteCodeCompiler.compile(typeDict);
var compiler = new Compiler();
var typeDict = compiler.compileSrc(src);
StringBuilder sb = new StringBuilder();
for (Symbol s : typeDict.bindings.values()) {
if (s instanceof Symbol.FunctionTypeSymbol f) {
var functionBuilder = (BytecodeFunction) f.code();
var functionBuilder = (CompiledFunction) f.code();
sb.append("func ").append(f.name).append("\n");
sb.append("Before SSA\n");
sb.append("==========\n");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,16 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.interpreter;

import com.compilerprogramming.ezlang.interpreter.Interpreter;
import com.compilerprogramming.ezlang.interpreter.Value;
import com.compilerprogramming.ezlang.lexer.Lexer;
import com.compilerprogramming.ezlang.parser.Parser;
import com.compilerprogramming.ezlang.semantic.SemaAssignTypes;
import com.compilerprogramming.ezlang.semantic.SemaDefineTypes;
import com.compilerprogramming.ezlang.types.Symbol;
import com.compilerprogramming.ezlang.types.TypeDictionary;
import com.compilerprogramming.ezlang.compiler.Compiler;
import org.junit.Assert;
import org.junit.Test;

import java.util.BitSet;

public class TestInterpreter {

Value compileAndRun(String src, String mainFunction) {
Parser parser = new Parser();
var program = parser.parse(new Lexer(src));
var typeDict = new TypeDictionary();
var sema = new SemaDefineTypes(typeDict);
sema.analyze(program);
var sema2 = new SemaAssignTypes(typeDict);
sema2.analyze(program);
var byteCodeCompiler = new BytecodeCompiler();
byteCodeCompiler.compile(typeDict);
StringBuilder sb = new StringBuilder();
for (Symbol s : typeDict.bindings.values()) {
if (s instanceof Symbol.FunctionTypeSymbol f) {
var functionBuilder = (BytecodeFunction) f.code();
BasicBlock.toStr(sb, functionBuilder.entry, new BitSet());
}
}
System.out.println(sb.toString());
var compiler = new Compiler();
var typeDict = compiler.compileSrc(src);
var compiled = compiler.dumpIR(typeDict);
System.out.println(compiled);
var interpreter = new Interpreter(typeDict);
return interpreter.run(mainFunction);
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.compilerprogramming.ezlang.bytecode;
package com.compilerprogramming.ezlang.compiler;

import java.util.ArrayList;
import java.util.BitSet;
Expand All @@ -25,6 +25,7 @@ public void addSuccessor(BasicBlock successor) {
successors.add(successor);
successor.predecessors.add(this);
}

public static StringBuilder toStr(StringBuilder sb, BasicBlock bb, BitSet visited)
{
if (visited.get(bb.bid))
Expand Down
Loading
Loading