1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-03 12:07:26 +00:00

Now parsing array declarations

This commit is contained in:
jespergravgaard 2017-05-25 02:24:18 +02:00
parent 15b1dc60fe
commit 6376029dbf
13 changed files with 191 additions and 52 deletions

View File

@ -187,7 +187,7 @@ public class AsmFragment {
}
} else if (value instanceof ConstantInteger) {
ConstantInteger intValue = (ConstantInteger) value;
if (intValue.getType().equals(SymbolType.BYTE)) {
if (intValue.getType().equals(SymbolTypeBasic.BYTE)) {
String name = "coby" + nextConstByteIdx++;
bindings.put(name, value);
return name;
@ -223,7 +223,7 @@ public class AsmFragment {
}
} else if (boundValue instanceof ConstantInteger) {
ConstantInteger boundInt = (ConstantInteger) boundValue;
if (boundInt.getType().equals(SymbolType.BYTE)) {
if (boundInt.getType().equals(SymbolTypeBasic.BYTE)) {
bound = Integer.toString(boundInt.getNumber());
} else {
throw new RuntimeException("Bound Value Type not implemented " + boundValue);

View File

@ -22,7 +22,7 @@ public class Label implements Symbol {
}
public SymbolType getType() {
return SymbolType.LABEL;
return SymbolTypeBasic.LABEL;
}
@Override

View File

@ -0,0 +1,91 @@
package dk.camelot64.kickc.icl;
import dk.camelot64.kickc.parser.KickCBaseVisitor;
import dk.camelot64.kickc.parser.KickCParser;
import org.antlr.v4.runtime.tree.TerminalNode;
/** Capable of evaluating constants directly on the parse tree. */
public class ParseTreeConstantEvaluator extends KickCBaseVisitor<Constant> {
/**
* Attempt to evaluate a constant expression.
*
* @param expr The expression to evaluate
* @return The constant value of the expression. null if the expression is not constant.
*/
public static Constant evaluate(KickCParser.ExprContext expr) {
return (new ParseTreeConstantEvaluator()).visit(expr);
}
@Override
public Constant visitExprNumber(KickCParser.ExprNumberContext ctx) {
Number number = NumberParser.parseLiteral(ctx.getText());
if(number instanceof Integer) {
return new ConstantInteger((Integer) number);
} else {
return new ConstantDouble((Double) number);
}
}
@Override
public Constant visitExprString(KickCParser.ExprStringContext ctx) {
return new ConstantString(ctx.getText());
}
@Override
public Constant visitExprBool(KickCParser.ExprBoolContext ctx) {
return new ConstantBool(Boolean.getBoolean(ctx.getText()));
}
@Override
public Constant visitExprPar(KickCParser.ExprParContext ctx) {
return visit(ctx.expr());
}
@Override
public Constant visitExprCast(KickCParser.ExprCastContext ctx) {
return visit(ctx.expr());
}
@Override
public Constant visitExprCall(KickCParser.ExprCallContext ctx) {
throw new RuntimeException("Not implemented!");
}
@Override
public Constant visitExprArray(KickCParser.ExprArrayContext ctx) {
throw new RuntimeException("Not implemented!");
}
@Override
public Constant visitExprId(KickCParser.ExprIdContext ctx) {
throw new RuntimeException("Not implemented!");
}
@Override
public Constant visitInitExpr(KickCParser.InitExprContext ctx) {
return visit(ctx.expr());
}
@Override
public Constant visitInitList(KickCParser.InitListContext ctx) {
throw new RuntimeException("Not implemented!");
}
@Override
public Constant visitExprUnary(KickCParser.ExprUnaryContext ctx) {
Constant sub = visit(ctx.expr());
String op = ((TerminalNode)ctx.getChild(0)).getSymbol().getText();
Operator operator = new Operator(op);
return Pass2ConstantPropagation.calculateUnary(operator, sub);
}
@Override
public Constant visitExprBinary(KickCParser.ExprBinaryContext ctx) {
Constant left = this.visit(ctx.expr(0));
Constant right = this.visit(ctx.expr(1));
String op = ((TerminalNode)ctx.getChild(1)).getSymbol().getText();
Operator operator = new Operator(op);
return Pass2ConstantPropagation.calculateBinary(operator, left, right);
}
}

View File

@ -174,7 +174,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
@Override
public SymbolType visitTypeSimple(KickCParser.TypeSimpleContext ctx) {
return SymbolType.get(ctx.getText());
return SymbolTypeBasic.get(ctx.getText());
}
@Override
@ -184,7 +184,13 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
@Override
public SymbolType visitTypeArray(KickCParser.TypeArrayContext ctx) {
throw new RuntimeException("Not implemented");
SymbolType elementType = (SymbolType) visit(ctx.typeDecl());
Constant size = ParseTreeConstantEvaluator.evaluate(ctx.expr());
if(size instanceof ConstantInteger) {
return new SymbolTypeArray(elementType, ((ConstantInteger) size).getNumber());
} else {
throw new RuntimeException("Array size not a constant integer "+ctx.getText());
}
}
@Override

View File

@ -95,6 +95,13 @@ public class Pass2ConstantPropagation extends Pass2Optimization {
return new ConstantDouble(getDouble(c1) + getDouble(c2));
}
}
case "*": {
if (c1 instanceof ConstantInteger && c2 instanceof ConstantInteger) {
return new ConstantInteger(getInteger(c1) * getInteger(c2));
} else {
return new ConstantDouble(getDouble(c1) * getDouble(c2));
}
}
default:
throw new RuntimeException("Unhandled Binary Operator " + operator.getOperator());
}

View File

@ -16,9 +16,9 @@ public class Pass3RegisterAllocation {
int currentZp = 2;
for (Variable var : symbols.getAllVariables()) {
if(var instanceof VariableIntermediate || var instanceof VariableVersion)
if(var.getType().equals(SymbolType.BYTE)) {
if(var.getType().equals(SymbolTypeBasic.BYTE)) {
allocation.allocate(var, new RegisterAllocation.RegisterZpByte(currentZp++));
} else if(var.getType().equals(SymbolType.BOOLEAN)) {
} else if(var.getType().equals(SymbolTypeBasic.BOOLEAN)) {
allocation.allocate(var, new RegisterAllocation.RegisterZpBool(currentZp++));
}
}

View File

@ -10,7 +10,7 @@ public class PassTypeInference {
if (statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;
Variable symbol = (Variable) assignment.getLValue();
if (SymbolType.VAR.equals(symbol.getType())) {
if (SymbolTypeBasic.VAR.equals(symbol.getType())) {
// Unresolved symbol - perform inference
Operator operator = assignment.getOperator();
if (operator == null || assignment.getRValue1() == null) {
@ -46,37 +46,40 @@ public class PassTypeInference {
case "||":
case "and":
case "or":
return SymbolType.BOOLEAN;
return SymbolTypeBasic.BOOLEAN;
case "+":
case "-":
case "*":
case "/":
if (type1.equals(SymbolType.WORD) || type2.equals(SymbolType.WORD)) {
return SymbolType.WORD;
if (type1.equals(SymbolTypeBasic.WORD) || type2.equals(SymbolTypeBasic.WORD)) {
return SymbolTypeBasic.WORD;
} else {
return SymbolType.BYTE;
return SymbolTypeBasic.BYTE;
}
default:
return SymbolType.VAR;
throw new RuntimeException("Type inference case not handled "+type1+" "+operator+" "+type2);
}
}
public static SymbolType inferType(RValue rValue) {
SymbolType type = SymbolType.VAR;
SymbolType type = null;
if (rValue instanceof Symbol) {
Symbol rSymbol = (Symbol) rValue;
type = rSymbol.getType();
} else if (rValue instanceof ConstantInteger) {
ConstantInteger rInt = (ConstantInteger) rValue;
if (rInt.getNumber() < 256) {
type = SymbolType.BYTE;
type = SymbolTypeBasic.BYTE;
} else {
type = SymbolType.WORD;
type = SymbolTypeBasic.WORD;
}
} else if (rValue instanceof ConstantString) {
type = SymbolType.STRING;
type = SymbolTypeBasic.STRING;
} else if (rValue instanceof ConstantBool) {
type = SymbolType.BOOLEAN;
type = SymbolTypeBasic.BOOLEAN;
}
if(type==null) {
throw new RuntimeException("Cannot infer type for "+rValue);
}
return type;
}

View File

@ -43,7 +43,7 @@ public class SymbolTable {
}
public VariableUnversioned newVariableDeclaration(String name, String type) {
SymbolType symbolType = SymbolType.get(type);
SymbolType symbolType = SymbolTypeBasic.get(type);
VariableUnversioned symbol = new VariableUnversioned(name, symbolType);
addSymbol(symbol);
return symbol;
@ -55,7 +55,7 @@ public class SymbolTable {
public VariableIntermediate newIntermediateAssignment() {
String name = "$"+intermediateVarCount++;
VariableIntermediate symbol = new VariableIntermediate(name, SymbolType.VAR);
VariableIntermediate symbol = new VariableIntermediate(name, SymbolTypeBasic.VAR);
addSymbol(symbol);
return symbol;
}

View File

@ -1,33 +1,8 @@
package dk.camelot64.kickc.icl;
/** Symbol Types */
public enum SymbolType {
BYTE("byte"),
WORD("word"),
STRING("string"),
BOOLEAN("boolean"),
LABEL("label"),
VAR("var");
private String typeName;
SymbolType(String typeName) {
this.typeName = typeName;
}
public String getTypeName() {
return typeName;
}
public static SymbolType get(String name) {
switch (name) {
case "byte": return BYTE;
case "word": return WORD;
case "string": return STRING;
case "boolean": return BOOLEAN;
}
return null;
}
public interface SymbolType {
public String getTypeName();
}

View File

@ -0,0 +1,26 @@
package dk.camelot64.kickc.icl;
/** A fixed size array of another type */
public class SymbolTypeArray implements SymbolType {
private SymbolType elementType;
private int size;
public SymbolTypeArray(SymbolType elementType, int size) {
this.elementType = elementType;
this.size = size;
}
public SymbolType getElementType() {
return elementType;
}
public int getSize() {
return size;
}
@Override
public String getTypeName() {
return elementType.getTypeName()+"["+size+"]";
}
}

View File

@ -0,0 +1,33 @@
package dk.camelot64.kickc.icl;
/** Basic Symbol Types */
public enum SymbolTypeBasic implements SymbolType {
BYTE("byte"),
WORD("word"),
STRING("string"),
BOOLEAN("boolean"),
LABEL("label"),
VAR("var");
private String typeName;
SymbolTypeBasic(String typeName) {
this.typeName = typeName;
}
public String getTypeName() {
return typeName;
}
public static SymbolTypeBasic get(String name) {
switch (name) {
case "byte": return BYTE;
case "word": return WORD;
case "string": return STRING;
case "boolean": return BOOLEAN;
}
return null;
}
}

View File

@ -13,7 +13,7 @@ import java.util.List;
/** Test my KickC Grammar */
public class Main {
public static void main(String[] args) throws IOException {
final String fileName = "src/dk/camelot64/kickc/test/fib.kc";
final String fileName = "src/dk/camelot64/kickc/test/mem.kc";
final CharStream input = CharStreams.fromFileName(fileName);
System.out.println(input.toString());
KickCLexer lexer = new KickCLexer(input);

View File

@ -1,12 +1,10 @@
// Array declaration & allocation (allocated in same memory space as the program)
byte[64] idtab;
byte[8*8] idtab;
// Array assignment
idtab[0] = 12;
// Using array indexing
byte id6 = idtab[1];
//byte id6 = idtab[1];