Skip to content
35 changes: 32 additions & 3 deletions src/tile/AntlrToExpression.java
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ public Expression visitFuncCallExpression(FuncCallExpressionContext ctx) {
is_native = true;
} catch (Exception e) {
Log.error(line + ":" + col + ": function " + funcId + " is not defined before called.");
return null; // FIXME: find a better way and consider func overloading as well for the future!
}
}

Expand Down Expand Up @@ -357,8 +358,31 @@ public Expression visitLogicalAndExpression(LogicalAndExpressionContext ctx) {

@Override
public Expression visitLogicalOrExpression(LogicalOrExpressionContext ctx) {
// TODO Auto-generated method stub
return super.visitLogicalOrExpression(ctx);
if (ctx.logicalAndExpression().size() == 1) {
return visit(ctx.logicalAndExpression(0));
}

// Otherwise, process the operator and operands.
Expression left = visit(ctx.logicalAndExpression(0)); // The first operand.
for (int i = 1; i < ctx.logicalAndExpression().size(); i++) {
// Get the operator (* or /).
String operator = ctx.getChild((i * 2) - 1).getText(); // Operators are at odd indices.

// Visit the right operand.
Expression right = visit(ctx.logicalAndExpression(i));

String lhs_type = left.getType();
String rhs_type = right.getType();

if (!lhs_type.equals("bool") || !rhs_type.equals("bool")) {
int line = ctx.stop.getLine();
int col = ctx.stop.getCharPositionInLine();
Log.warning(line + ":" + col + ": logical expressions type should be a bool type!");
}
TypeInfoLogicalBinop type = TypeResolver.resolveBinopLogicalType(lhs_type, rhs_type);
left = new LogicalExpression(left, operator, right, type);
}
return left;
}

@Override
Expand Down Expand Up @@ -523,7 +547,12 @@ public Expression visitArrayIndexAccessor(ArrayIndexAccessorContext ctx) {
int reducedDim = exprs.size();
typeInfo = TypeResolver.resolveArrayIndexAccessor(varType.toString(), reducedDim);

return new ArrayIndexAccessor(typeInfo, tasmIdx, exprs);
ArrayIndexAccessor aia = new ArrayIndexAccessor(typeInfo, tasmIdx, exprs);
if (isGlobal.get() == true) {
aia.setAsGlobal();
}

return aia;
}

@Override
Expand Down
92 changes: 60 additions & 32 deletions src/tile/AntlrToStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
import gen.antlr.tile.tileParser.ProgramContext;
import gen.antlr.tile.tileParser.ReturnStmtContext;
import gen.antlr.tile.tileParser.SelectionStmtContext;
import gen.antlr.tile.tileParser.StructDefinitionContext;
import gen.antlr.tile.tileParser.VariableAssignmentContext;
import gen.antlr.tile.tileParser.VariableDeclerationContext;
import gen.antlr.tile.tileParser.VariableDefinitionContext;
import gen.antlr.tile.tileParser.VariableStmtContext;
import gen.antlr.tile.tileParser.TasmBlockContext;
import gen.antlr.tile.tileParser.TypeDefinitionContext;
import gen.antlr.tile.tileParser.WhileStmtContext;
import gen.antlr.tile.tileParser.ForInitialContext;
import gen.antlr.tile.tileParserBaseVisitor;
Expand All @@ -45,6 +47,19 @@

public class AntlrToStatement extends tileParserBaseVisitor<Statement> {

public static boolean staticReturnAnalysis(BlockStmt blck) {
for (Statement stmt : blck.statements) {
if (stmt instanceof ReturnStmt) {
return true;
} else if (stmt instanceof BlockStmt) {
if (staticReturnAnalysis((BlockStmt)stmt)) {
return true;
}
}
}
return false;
}

@Override
public Statement visitBlockStmt(BlockStmtContext ctx) {
BlockStmt blockStmt = null;
Expand Down Expand Up @@ -156,6 +171,20 @@ public Statement visitBlockStmt(BlockStmtContext ctx) {
if (Program.parentStack.isEmpty() || !(Program.parentStack.peek() instanceof ForStmt)) {
Program.blockStack.remove(Program.blockStack.size() - 1);
}

// static analysis if func returns the correct thing
if (parent instanceof FuncDefStmtContext) {
if (!(func.getReturn_type().result_type.equals("void"))) {
boolean isReturned = staticReturnAnalysis(blockStmt);
if (!isReturned) {
int line = ((FuncDefStmtContext)parentFunc).IDENTIFIER().getSymbol().getLine();
int col = ((FuncDefStmtContext)parentFunc).IDENTIFIER().getSymbol().getCharPositionInLine();
Log.error(line + ":" + col + ": function should return!");
}
}
}


return blockStmt;
}

Expand All @@ -180,7 +209,18 @@ public Statement visitBlockStmt(BlockStmtContext ctx) {
}
blockStmt.addStatement(stmt);
}


// static analysis if func returns the correct thing
if (parent instanceof FuncDefStmtContext) {
if (!(func.getReturn_type().result_type.equals("void"))) {
boolean isReturned = staticReturnAnalysis(blockStmt);
if (!isReturned) {
int line = ((FuncDefStmtContext)parentFunc).IDENTIFIER().getSymbol().getLine();
int col = ((FuncDefStmtContext)parentFunc).IDENTIFIER().getSymbol().getCharPositionInLine();
Log.error(line + ":" + col + ": function should return!");
}
}
}

if (Program.parentStack.isEmpty() || !(Program.parentStack.peek() instanceof ForStmt)) {
Program.blockStack.remove(Program.blockStack.size() - 1);
Expand Down Expand Up @@ -263,38 +303,26 @@ else if (ctx.variableStmt() != null) {
return result;
}

// @Override
// public Statement visitTypeDefinition(TypeDefinitionContext ctx) {
// String name = ctx.IDENTIFIER().getText();

// if (ctx.structDefinition() != null) {
// TypeDefinition def = new TypeDefinition(name, TypeDefinition.Kind.STRUCT);
// List<String> fields = new ArrayList<>();

// for (var fieldCtx : ctx.structDefinition().fieldDefinition()) {
// String fieldName = fieldCtx.IDENTIFIER().getText();
// String fieldType = fieldCtx.typeName().getText();
// fields.add(new String(fieldName, fieldType));
// }

// def.fields = fields;
// TypeResolver.userTypeDefs.put(name, def);

// } else if (ctx.typeUnion() != null) {
// TypeDefinition def = new TypeDefinition(name, TypeDefinition.Kind.UNION);

// List<String> variants = ctx.typeUnion().IDENTIFIER()
// .stream()
// .map(ParseTree::getText)
// .toList();

// def.variants = variants;
// TypeResolver.userTypeDefs.put(name, def);
// }
@Override
public Statement visitTypeDefinition(TypeDefinitionContext ctx) {
String typeName = ctx.IDENTIFIER().getText();
List<TypeDefinition.Field> fields = null;
TypeDefinition.Kind kind = null;
if (ctx.structDefinition() != null) {
fields = new ArrayList<>();
kind = TypeDefinition.Kind.STRUCT;
for (int i = 0; i < ctx.structDefinition().fieldDefinition().size(); i++) {
String id = ctx.structDefinition().fieldDefinition(i).IDENTIFIER().getText();
String type = ctx.structDefinition().fieldDefinition(i).typeName().getText();
TypeDefinition.Field field = new TypeDefinition.Field(id, type);
fields.add(field);
}
}

// return new ExpressionStmt(null, false);
// return super.visitTypeDefinition(ctx);
// }
TypeDefinition td = new TypeDefinition(typeName, kind, fields);
TypeResolver.userTypeDefs.put(typeName, td);
return td;
}

@Override
public Statement visitFuncDefStmt(FuncDefStmtContext ctx) {
Expand Down
24 changes: 21 additions & 3 deletions src/tile/ast/expr/ArrayIndexAccessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,47 @@ public class ArrayIndexAccessor implements Expression {
TypeInfoArray typeInfo;
private int identifierTasmIdx;
List<Expression> indicies;
boolean isGlobal;

public ArrayIndexAccessor(TypeInfoArray typeInfo, int identifierTasmIdx, List<Expression> indicies) {
this.typeInfo = typeInfo;
this.identifierTasmIdx = identifierTasmIdx;
this.indicies = indicies;
isGlobal = false;
}

private String genLoadCode(String generatedCode) {
if (isGlobal) {
generatedCode += " gload " + identifierTasmIdx + "\n";
} else {
generatedCode += " load " + identifierTasmIdx + "\n";
}
return generatedCode;
}

@Override
public String generateTasm(String generatedCode) {
generatedCode += " load " + identifierTasmIdx + "\n";
generatedCode = genLoadCode(generatedCode);
generatedCode += " deref ; dereferance\n";
// FIXME:
generatedCode += " derefb " + typeInfo.element_size + " ; dereferance\n";
generatedCode = indicies.get(0).generateTasm(generatedCode);
generatedCode += " push " + typeInfo.element_size + "\n";
generatedCode += " mult\n";
generatedCode += " add\n";
generatedCode += " deref ; dereferance\n";
return generatedCode;


// generatedCode += " derefb " + typeInfo.element_size + " ; dereferance\n";
// generatedCode += " deref ; dereferance\n";
}

@Override
public String getType() {
return typeInfo.type;
}

public void setAsGlobal() {
isGlobal = true;
}

}
2 changes: 2 additions & 0 deletions src/tile/ast/expr/LogicalExpression.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public String generateTasm(String generatedCode) {

if (operator.equals("&&")) {
generatedCode += " and\n";
} else if (operator.equals("||")) {
generatedCode += " or\n";
}

return generatedCode;
Expand Down
17 changes: 9 additions & 8 deletions src/tile/ast/stmt/TypeDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,26 @@ public enum Kind {
UNION
}

public String name;
public String typeName;
public Kind kind;

public static class Field {
public String name;
public String id;
public String type;

public Field(String name, String type) {
this.name = name;
public Field(String id, String type) {
this.id = id;
this.type = type;
}
}

public List<Field> fields; // for struct
public List<String> variants; // for union
private List<Field> fields; // for struct
private List<String> variants; // for union

public TypeDefinition(String name, Kind kind) {
this.name = name;
public TypeDefinition(String typeName, Kind kind, List<Field> fields) {
this.typeName = typeName;
this.kind = kind;
this.fields = fields;
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions src/tile/ast/stmt/VariableDecleration.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public String generateTasm(String generatedCode) {
// 0 for all defined types
// user defined null (0)
if (isGlobal) {
generatedCode += "push 0\n";
generatedCode += "gstore " + tasmIdx + " ; " + typeInfo + " " + varId + "\n";
// generatedCode += "push 0\n";
// generatedCode += "gstore " + tasmIdx + " ; " + typeInfo + " " + varId + "\n";
} else {
generatedCode += " push 0\n";
generatedCode += " store " + tasmIdx + " ; " + typeInfo + " " + varId + "\n";
Expand Down
5 changes: 5 additions & 0 deletions tileParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ objectLiteralFieldAssignment
: '.' IDENTIFIER assignmentOperator expression
;

objectAccessor
: IDENTIFIER '.' IDENTIFIER
;

unaryExpression
: incDecOperator primaryExpression
| primaryExpression incDecOperator
Expand Down Expand Up @@ -233,6 +237,7 @@ variableDefinition
variableAssignment
: IDENTIFIER assignmentOperator expressionStmt
| arrayIndexAccessorSetter assignmentOperator expressionStmt
| objectAccessor assignmentOperator expressionStmt
;

loopStmt
Expand Down