From 38bfac45cd6a3a355e1d143b06e1d7a4cf57868f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Muhammed=20Yasinhan=20Ya=C5=9Far?= Date: Thu, 17 Apr 2025 09:33:23 +0300 Subject: [PATCH 1/7] deref and mult operations are built-in in vm --- src/tile/ast/stmt/VariableAssignment.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tile/ast/stmt/VariableAssignment.java b/src/tile/ast/stmt/VariableAssignment.java index 0f61939..536ffa7 100644 --- a/src/tile/ast/stmt/VariableAssignment.java +++ b/src/tile/ast/stmt/VariableAssignment.java @@ -58,10 +58,8 @@ else if (typeInfo.var_type.equals("float") && typeInfo.expr_type.equals("int")) generatedCode += "store " + tasmIdx + " ; " + typeInfo.var_type + " " + varId + "\n"; } else { generatedCode += " load " + tasmIdx + "\n"; - generatedCode += " deref ; dereferance\n"; generatedCode = indicies.get(0).generateTasm(generatedCode); generatedCode += " push " + typeInfo.info_array.element_size + "\n"; - generatedCode += " mult\n"; generatedCode += " hset\n"; } From 5888886e7ec94f41a5b9c940318572da97101592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Muhammed=20Yasinhan=20Ya=C5=9Far?= Date: Thu, 8 May 2025 22:42:36 +0300 Subject: [PATCH 2/7] user defined types initialization started to implement --- src/tile/AntlrToExpression.java | 74 +++++++++++++++++++++++++++ src/tile/AntlrToStatement.java | 29 ++++++++++- src/tile/ast/expr/ObjectLiteral.java | 56 ++++++++++++++++++++ src/tile/ast/stmt/TypeDefinition.java | 8 ++- src/tile/ast/types/TypeResolver.java | 15 ++++++ tileParser.g4 | 4 +- 6 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 src/tile/ast/expr/ObjectLiteral.java diff --git a/src/tile/AntlrToExpression.java b/src/tile/AntlrToExpression.java index ad1044c..b61a490 100644 --- a/src/tile/AntlrToExpression.java +++ b/src/tile/AntlrToExpression.java @@ -18,6 +18,8 @@ import gen.antlr.tile.tileParser.LogicalAndExpressionContext; import gen.antlr.tile.tileParser.LogicalOrExpressionContext; import gen.antlr.tile.tileParser.MultiplicativeExpressionContext; +import gen.antlr.tile.tileParser.ObjectAccessorContext; +import gen.antlr.tile.tileParser.ObjectLiteralExpressionContext; import gen.antlr.tile.tileParser.PrimaryExpressionContext; import gen.antlr.tile.tileParser.RelationalExpressionContext; import gen.antlr.tile.tileParser.ShiftExpressionContext; @@ -40,10 +42,12 @@ import tile.ast.expr.FuncCallExpression; import tile.ast.expr.LogicalExpression; import tile.ast.expr.MultiplicativeExpression; +import tile.ast.expr.ObjectLiteral; import tile.ast.expr.PrimaryExpression; import tile.ast.expr.RelationalExpression; import tile.ast.expr.ShiftExpression; import tile.ast.expr.UnaryExpression; +import tile.ast.stmt.TypeDefinition; import tile.ast.types.TypeResolver; import tile.ast.types.TypeResolver.TypeFuncCall; import tile.ast.types.TypeResolver.TypeInfoArray; @@ -573,4 +577,74 @@ public Expression visitForUpdate(ForUpdateContext ctx) { return result; } + @Override + public Expression visitObjectLiteralExpression(ObjectLiteralExpressionContext ctx) { + String type = ""; + if (ctx.IDENTIFIER() != null) { + // Implemented + /* + a: Animal = Animal { + .name = "asd", + .age = 10 + }; + */ + type = ctx.IDENTIFIER().getText(); + TypeDefinition td = TypeResolver.userTypeDefs.get(type); + if (td == null) { + int line = ctx.IDENTIFIER().getSymbol().getLine(); + int col = ctx.IDENTIFIER().getSymbol().getCharPositionInLine(); + Log.error(line + ":" + col + ": literal type " + type + " cannot be resolved!"); + } else { + // traverse {.identifier} and typedefinition fields to see if they matched + if (ctx.objectLiteralFieldAssignment() != null) { + int[] assignedFields = new int[td.getFields().size()]; + List assignedFieldsCheck = new ArrayList<>(); // to check if there is such a field + for (int i = 0; i < ctx.objectLiteralFieldAssignment().size(); i++) { + String objLitFieldId = ctx.objectLiteralFieldAssignment(i).IDENTIFIER().getText(); + + for (int j = 0; j < td.getFields().size(); j++) { + if (objLitFieldId.equals(td.getFields().get(j).id)) { + assignedFieldsCheck.add(i); + assignedFields[j] = 1; + break; + } + } + + if (!assignedFieldsCheck.contains(i)) { + int line = ctx.objectLiteralFieldAssignment(i).IDENTIFIER().getSymbol().getLine(); + int col = ctx.objectLiteralFieldAssignment(i).IDENTIFIER().getSymbol().getCharPositionInLine(); + Log.error(line + ":" + col + ": " + type + " doesn't have a field " + objLitFieldId + "!"); + } + } + + ObjectLiteral objLit = new ObjectLiteral(td, type, assignedFields); + return objLit; + } + } + + } else { + // TODO: Not implemented inferring type + /* + a: Animal = {0}; + a: Animal = { + .name = "asd", + .age = 10 + }; + */ + int line = ctx.PUNC_LEFTBRACE().getSymbol().getLine(); + int col = ctx.PUNC_LEFTBRACE().getSymbol().getCharPositionInLine(); + Log.error(line + ":" + col + ": for custom literal type, type inferring is not implemented yet!"); + } + + + + return super.visitObjectLiteralExpression(ctx); + } + + @Override + public Expression visitObjectAccessor(ObjectAccessorContext ctx) { + // TODO Auto-generated method stub + return super.visitObjectAccessor(ctx); + } + } diff --git a/src/tile/AntlrToStatement.java b/src/tile/AntlrToStatement.java index 5eeedb6..2b62da5 100644 --- a/src/tile/AntlrToStatement.java +++ b/src/tile/AntlrToStatement.java @@ -314,7 +314,8 @@ public Statement visitTypeDefinition(TypeDefinitionContext ctx) { 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); + int type_size = TypeResolver.resolveFieldTypeSize(type); + TypeDefinition.Field field = new TypeDefinition.Field(id, type, type_size); fields.add(field); } } @@ -522,13 +523,24 @@ public Statement visitVariableAssignment(VariableAssignmentContext ctx) { @Override public Statement visitVariableDecleration(VariableDeclerationContext ctx) { - // TODO Auto-generated method stub // int a; // Cat b; String type = ctx.typeName().getText(); String varId = ctx.IDENTIFIER().getText(); + if (ctx.typeName().primaryTypeName() != null) { + if (ctx.typeName().primaryTypeName().IDENTIFIER() != null) { + TypeDefinition td = TypeResolver.userTypeDefs.get(type); + + if (td == null) { + int line = ctx.typeName().primaryTypeName().IDENTIFIER().getSymbol().getLine(); + int col = ctx.typeName().primaryTypeName().IDENTIFIER().getSymbol().getCharPositionInLine(); + Log.error(line + ":" + col + ": type " + type + " cannot be resolved!"); + } + } + } + VariableDecleration v_dec = new VariableDecleration(type, varId); // if it is global @@ -545,6 +557,19 @@ public Statement visitVariableDecleration(VariableDeclerationContext ctx) { public Statement visitVariableDefinition(VariableDefinitionContext ctx) { String type = ctx.typeName().getText(); String varId = ctx.IDENTIFIER().getText(); + + if (ctx.typeName().primaryTypeName() != null) { + if (ctx.typeName().primaryTypeName().IDENTIFIER() != null) { + TypeDefinition td = TypeResolver.userTypeDefs.get(type); + + if (td == null) { + int line = ctx.typeName().primaryTypeName().IDENTIFIER().getSymbol().getLine(); + int col = ctx.typeName().primaryTypeName().IDENTIFIER().getSymbol().getCharPositionInLine(); + Log.error(line + ":" + col + ": type " + type + " cannot be resolved!"); + } + } + } + Statement exprStmt = visit(ctx.expressionStmt()); String exprType = ((ExpressionStmt)exprStmt).getType(); diff --git a/src/tile/ast/expr/ObjectLiteral.java b/src/tile/ast/expr/ObjectLiteral.java new file mode 100644 index 0000000..7331e5b --- /dev/null +++ b/src/tile/ast/expr/ObjectLiteral.java @@ -0,0 +1,56 @@ +package tile.ast.expr; + +import tile.ast.base.Expression; +import tile.ast.stmt.TypeDefinition; + +public class ObjectLiteral implements Expression { + + private String type; + private TypeDefinition typeDef; + private int[] assignedFields; + + public ObjectLiteral(TypeDefinition typeDef, String type, int[] assignedFields) { + this.type = type; + this.typeDef = typeDef; + this.assignedFields = assignedFields; + } + + @Override + public String generateTasm(String generatedCode) { + // allocate + int totalSize = 0; + for (int i = 0; i < typeDef.getFields().size(); i++) { + totalSize += typeDef.getFields().get(i).type_size; + } + generatedCode += " ; type " + type + "\n"; + generatedCode += " push " + totalSize + "\n"; + generatedCode += " push 0\n"; + generatedCode += " halloc\n"; + // set + /* + push 50 + load 1 + push 0 + push 4 + hset + FIXME: fix here! + for (int i = 0; i < typeDef.getFields().size(); i++) { + if (assignedFields[i] == 1) { + + } + + int size = typeDef.getFields().get(i).type_size; + generatedCode += " push " + size + "\n"; + generatedCode += " hset\n"; + } + */ + + return generatedCode; + } + + @Override + public String getType() { + return type; + } + +} diff --git a/src/tile/ast/stmt/TypeDefinition.java b/src/tile/ast/stmt/TypeDefinition.java index c795070..61cf67f 100644 --- a/src/tile/ast/stmt/TypeDefinition.java +++ b/src/tile/ast/stmt/TypeDefinition.java @@ -16,10 +16,12 @@ public enum Kind { public static class Field { public String id; public String type; + public int type_size; - public Field(String id, String type) { + public Field(String id, String type, int type_size) { this.id = id; this.type = type; + this.type_size = type_size; } } @@ -39,4 +41,8 @@ public String generateTasm(String generatedCode) { */ return generatedCode; } + + public List getFields() { + return fields; + } } diff --git a/src/tile/ast/types/TypeResolver.java b/src/tile/ast/types/TypeResolver.java index 5c1617e..1affca0 100644 --- a/src/tile/ast/types/TypeResolver.java +++ b/src/tile/ast/types/TypeResolver.java @@ -164,6 +164,21 @@ private static int resolveArrayTypeSize(String type) { return -1; } + public static int resolveFieldTypeSize(String type) { + if (isArrayType(type)) { + return 8; // FIXME: check if this is on x64 or x86 tvm (get it as cmd arg) + } + switch (type) { + case "int": + case "float": return 4; + case "char": return 1; + } + + // composite type + // FIXME: + return -1; + } + public static TypeInfoArray resolveArrayInitializerType(String type, int dimension) { TypeInfoArray typeInfo = new TypeInfoArray(); typeInfo.element_size = resolveArrayTypeSize(type); diff --git a/tileParser.g4 b/tileParser.g4 index d2565bd..b296add 100644 --- a/tileParser.g4 +++ b/tileParser.g4 @@ -78,9 +78,9 @@ primaryExpression | '(' expression ')' ; +// TODO: also allow zero initialize like {0} objectLiteralExpression - : - PUNC_LEFTBRACE ( objectLiteralFieldAssignment (PUNC_COMMA objectLiteralFieldAssignment)*)? PUNC_COMMA? PUNC_RIGHTBRACE + : IDENTIFIER? PUNC_LEFTBRACE ( objectLiteralFieldAssignment (PUNC_COMMA objectLiteralFieldAssignment)*)? PUNC_COMMA? PUNC_RIGHTBRACE ; objectLiteralFieldAssignment From e82f2af6d5ce67473c4476cad5e25fa9681822f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Muhammed=20Yasinhan=20Ya=C5=9Far?= Date: Thu, 8 May 2025 22:55:40 +0300 Subject: [PATCH 3/7] fields are changed as has tables instead of list --- src/tile/AntlrToExpression.java | 11 +---------- src/tile/AntlrToStatement.java | 13 ++++++++++--- src/tile/ast/expr/ObjectLiteral.java | 6 ++++-- src/tile/ast/stmt/TypeDefinition.java | 7 ++++--- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/tile/AntlrToExpression.java b/src/tile/AntlrToExpression.java index b61a490..8c590b5 100644 --- a/src/tile/AntlrToExpression.java +++ b/src/tile/AntlrToExpression.java @@ -598,19 +598,10 @@ public Expression visitObjectLiteralExpression(ObjectLiteralExpressionContext ct // traverse {.identifier} and typedefinition fields to see if they matched if (ctx.objectLiteralFieldAssignment() != null) { int[] assignedFields = new int[td.getFields().size()]; - List assignedFieldsCheck = new ArrayList<>(); // to check if there is such a field for (int i = 0; i < ctx.objectLiteralFieldAssignment().size(); i++) { String objLitFieldId = ctx.objectLiteralFieldAssignment(i).IDENTIFIER().getText(); - for (int j = 0; j < td.getFields().size(); j++) { - if (objLitFieldId.equals(td.getFields().get(j).id)) { - assignedFieldsCheck.add(i); - assignedFields[j] = 1; - break; - } - } - - if (!assignedFieldsCheck.contains(i)) { + if (td.getFields().get(objLitFieldId) == null) { int line = ctx.objectLiteralFieldAssignment(i).IDENTIFIER().getSymbol().getLine(); int col = ctx.objectLiteralFieldAssignment(i).IDENTIFIER().getSymbol().getCharPositionInLine(); Log.error(line + ":" + col + ": " + type + " doesn't have a field " + objLitFieldId + "!"); diff --git a/src/tile/AntlrToStatement.java b/src/tile/AntlrToStatement.java index 2b62da5..96ff7b8 100644 --- a/src/tile/AntlrToStatement.java +++ b/src/tile/AntlrToStatement.java @@ -4,6 +4,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @@ -306,17 +307,23 @@ else if (ctx.variableStmt() != null) { @Override public Statement visitTypeDefinition(TypeDefinitionContext ctx) { String typeName = ctx.IDENTIFIER().getText(); - List fields = null; + HashMap fields = null; TypeDefinition.Kind kind = null; if (ctx.structDefinition() != null) { - fields = new ArrayList<>(); + fields = new HashMap<>(); 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(); int type_size = TypeResolver.resolveFieldTypeSize(type); TypeDefinition.Field field = new TypeDefinition.Field(id, type, type_size); - fields.add(field); + if (!fields.containsKey(id)) { + fields.put(id, field); + } else { + int line = ctx.structDefinition().fieldDefinition(i).IDENTIFIER().getSymbol().getLine(); + int col = ctx.structDefinition().fieldDefinition(i).IDENTIFIER().getSymbol().getCharPositionInLine(); + Log.error(line + ":" + col + " " + id + " field is already defined in " + typeName + "!"); + } } } diff --git a/src/tile/ast/expr/ObjectLiteral.java b/src/tile/ast/expr/ObjectLiteral.java index 7331e5b..9245884 100644 --- a/src/tile/ast/expr/ObjectLiteral.java +++ b/src/tile/ast/expr/ObjectLiteral.java @@ -1,5 +1,7 @@ package tile.ast.expr; +import java.util.Map; + import tile.ast.base.Expression; import tile.ast.stmt.TypeDefinition; @@ -19,8 +21,8 @@ public ObjectLiteral(TypeDefinition typeDef, String type, int[] assignedFields) public String generateTasm(String generatedCode) { // allocate int totalSize = 0; - for (int i = 0; i < typeDef.getFields().size(); i++) { - totalSize += typeDef.getFields().get(i).type_size; + for (Map.Entry entry : typeDef.getFields().entrySet()) { + totalSize += entry.getValue().type_size; } generatedCode += " ; type " + type + "\n"; generatedCode += " push " + totalSize + "\n"; diff --git a/src/tile/ast/stmt/TypeDefinition.java b/src/tile/ast/stmt/TypeDefinition.java index 61cf67f..7d6be4a 100644 --- a/src/tile/ast/stmt/TypeDefinition.java +++ b/src/tile/ast/stmt/TypeDefinition.java @@ -1,5 +1,6 @@ package tile.ast.stmt; +import java.util.HashMap; import java.util.List; import tile.ast.base.Statement; @@ -25,10 +26,10 @@ public Field(String id, String type, int type_size) { } } - private List fields; // for struct + private HashMap fields; // for struct private List variants; // for union - public TypeDefinition(String typeName, Kind kind, List fields) { + public TypeDefinition(String typeName, Kind kind, HashMap fields) { this.typeName = typeName; this.kind = kind; this.fields = fields; @@ -42,7 +43,7 @@ public String generateTasm(String generatedCode) { return generatedCode; } - public List getFields() { + public HashMap getFields() { return fields; } } From 9ca28eb5a83c7fc215bb4391bf46b57872580964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Muhammed=20Yasinhan=20Ya=C5=9Far?= Date: Fri, 9 May 2025 17:49:03 +0300 Subject: [PATCH 4/7] object accessor started to implement --- src/tile/AntlrToExpression.java | 48 +++++++++++++++++++++++-- src/tile/AntlrToStatement.java | 4 +++ src/tile/ast/expr/ObjectAccessor.java | 52 +++++++++++++++++++++++++++ src/tile/ast/types/TypeResolver.java | 2 +- tileParser.g4 | 4 +++ 5 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 src/tile/ast/expr/ObjectAccessor.java diff --git a/src/tile/AntlrToExpression.java b/src/tile/AntlrToExpression.java index 8c590b5..137d013 100644 --- a/src/tile/AntlrToExpression.java +++ b/src/tile/AntlrToExpression.java @@ -42,6 +42,7 @@ import tile.ast.expr.FuncCallExpression; import tile.ast.expr.LogicalExpression; import tile.ast.expr.MultiplicativeExpression; +import tile.ast.expr.ObjectAccessor; import tile.ast.expr.ObjectLiteral; import tile.ast.expr.PrimaryExpression; import tile.ast.expr.RelationalExpression; @@ -634,8 +635,51 @@ public Expression visitObjectLiteralExpression(ObjectLiteralExpressionContext ct @Override public Expression visitObjectAccessor(ObjectAccessorContext ctx) { - // TODO Auto-generated method stub - return super.visitObjectAccessor(ctx); + String identifier = ctx.IDENTIFIER(0).getText(); + StringBuilder varType = new StringBuilder(); + int tasmIdx = -1; + AtomicBoolean isGlobal = new AtomicBoolean(false); + try { + tasmIdx = TasmSymbolGenerator.identifierScopeFind(identifier, varType, isGlobal); + // TODO: use isGlobal!!! + } catch (Exception e) { + int line = ctx.IDENTIFIER(0).getSymbol().getLine(); + int col = ctx.IDENTIFIER(0).getSymbol().getCharPositionInLine(); + Log.error(line + ":" + col + ": variable " + "'" + identifier + "' is not defined before use!"); + } + + String type = varType.toString(); + TypeDefinition td = TypeResolver.userTypeDefs.get(type); + + + if (ctx.objectAccessor() == null) { + String fieldId = ctx.IDENTIFIER(1).getText(); + if (td != null) { + td.getFields().get(fieldId); + if (td.getFields().get(fieldId) == null) { + int line = ctx.IDENTIFIER(1).getSymbol().getLine(); + int col = ctx.IDENTIFIER(1).getSymbol().getCharPositionInLine(); + Log.error(line + ":" + col + ": '" + identifier + ": " + type + "'' doesn't have a field " + fieldId + "!"); + } + } + + ObjectAccessor oa = new ObjectAccessor(fieldId, td, tasmIdx, null); + if (isGlobal.get() == true) { + oa.setAsGlobal(); + } + + return oa; + } else { + + ObjectAccessor accessor = (ObjectAccessor)visit(ctx.objectAccessor()); + + ObjectAccessor oa = new ObjectAccessor(null, td, tasmIdx, accessor); + if (isGlobal.get() == true) { + oa.setAsGlobal(); + } + + return oa; + } } } diff --git a/src/tile/AntlrToStatement.java b/src/tile/AntlrToStatement.java index 96ff7b8..bdb41bf 100644 --- a/src/tile/AntlrToStatement.java +++ b/src/tile/AntlrToStatement.java @@ -468,6 +468,8 @@ public Statement visitVariableAssignment(VariableAssignmentContext ctx) { String varId = ""; if (ctx.arrayIndexAccessorSetter() != null) { varId = ctx.arrayIndexAccessorSetter().IDENTIFIER().getText(); + } else if (ctx.objectAccessor() != null) { + varId = ctx.objectAccessor().IDENTIFIER(0).getText(); } else { varId = ctx.IDENTIFIER().getText(); } @@ -484,6 +486,8 @@ public Statement visitVariableAssignment(VariableAssignmentContext ctx) { if (ctx.arrayIndexAccessorSetter() != null) { line = ctx.arrayIndexAccessorSetter().IDENTIFIER().getSymbol().getLine(); col = ctx.arrayIndexAccessorSetter().IDENTIFIER().getSymbol().getCharPositionInLine(); + } else if (ctx.objectAccessor() != null) { + } else { line = ctx.IDENTIFIER().getSymbol().getLine(); col = ctx.IDENTIFIER().getSymbol().getCharPositionInLine(); diff --git a/src/tile/ast/expr/ObjectAccessor.java b/src/tile/ast/expr/ObjectAccessor.java new file mode 100644 index 0000000..5ce1cde --- /dev/null +++ b/src/tile/ast/expr/ObjectAccessor.java @@ -0,0 +1,52 @@ +package tile.ast.expr; + +import tile.ast.base.Expression; +import tile.ast.stmt.TypeDefinition; + +public class ObjectAccessor implements Expression { + private TypeDefinition typeDefinition; + private int identifierTasmIdx; + boolean isGlobal = false; + private String fieldId; + ObjectAccessor accessor; + + public void setAsGlobal() { + this.isGlobal = true; + } + + public ObjectAccessor(String fieldId, TypeDefinition typeDefinition, int identifierTasmIdx, ObjectAccessor accessor) { + this.identifierTasmIdx = identifierTasmIdx; + this.accessor = accessor; + this.typeDefinition = typeDefinition; + this.fieldId = fieldId; + } + + private String genLoadCode(String generatedCode) { + if (isGlobal) { + generatedCode += " gload " + identifierTasmIdx + "\n"; + } else { + generatedCode += " load " + identifierTasmIdx + "\n"; + } + return generatedCode; + } + + @Override + public String generateTasm(String generatedCode) { + int size = typeDefinition.getFields().get(fieldId).type_size; + int offset = 0; + + // TODO: implement here + generatedCode = genLoadCode(generatedCode); + generatedCode += " deref ; dereferance\n"; + generatedCode += " push " + offset + "\n"; + generatedCode += " add\n"; + generatedCode += " derefb " + size + " ; dereferance\n"; + return generatedCode; + } + + @Override + public String getType() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getType'"); + } +} diff --git a/src/tile/ast/types/TypeResolver.java b/src/tile/ast/types/TypeResolver.java index 1affca0..d12e1bb 100644 --- a/src/tile/ast/types/TypeResolver.java +++ b/src/tile/ast/types/TypeResolver.java @@ -165,7 +165,7 @@ private static int resolveArrayTypeSize(String type) { } public static int resolveFieldTypeSize(String type) { - if (isArrayType(type)) { + if (isArrayType(type) || type.equals("string")) { return 8; // FIXME: check if this is on x64 or x86 tvm (get it as cmd arg) } switch (type) { diff --git a/tileParser.g4 b/tileParser.g4 index b296add..fe839e8 100644 --- a/tileParser.g4 +++ b/tileParser.g4 @@ -48,6 +48,7 @@ expressionStmt expression : primaryExpression | unaryExpression + | objectAccessor | arrayIndexAccessor | arrayValuedInitializer | arraySizedInitializer @@ -89,6 +90,7 @@ objectLiteralFieldAssignment objectAccessor : IDENTIFIER '.' IDENTIFIER + | IDENTIFIER '.' objectAccessor ; unaryExpression @@ -154,6 +156,8 @@ castExpression | funcCallExpression | '(' typeName ')' arrayIndexAccessor | arrayIndexAccessor + | '(' typeName ')' objectAccessor + | objectAccessor ; multiplicativeExpression From a2f70f9360223ae34d304989458271a144d77755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Muhammed=20Yasinhan=20Ya=C5=9Far?= Date: Sat, 10 May 2025 04:51:47 +0300 Subject: [PATCH 5/7] imporovements on types of fields of userdefined types --- src/tile/AntlrToStatement.java | 21 +++++++++++++-- src/tile/ast/expr/ObjectAccessor.java | 6 ++--- src/tile/ast/stmt/TypeDefinition.java | 4 ++- src/tile/ast/stmt/VariableAssignment.java | 19 ++++++++++++-- src/tile/ast/types/TypeResolver.java | 31 ++++++++++++++++++++++- 5 files changed, 71 insertions(+), 10 deletions(-) diff --git a/src/tile/AntlrToStatement.java b/src/tile/AntlrToStatement.java index bdb41bf..e009f6e 100644 --- a/src/tile/AntlrToStatement.java +++ b/src/tile/AntlrToStatement.java @@ -22,6 +22,7 @@ import gen.antlr.tile.tileParser.LoopStmtContext; import gen.antlr.tile.tileParser.ImportStmtContext; import gen.antlr.tile.tileParser.NativeFuncDeclStmtContext; +import gen.antlr.tile.tileParser.ObjectAccessorContext; import gen.antlr.tile.tileParser.ProgramContext; import gen.antlr.tile.tileParser.ReturnStmtContext; import gen.antlr.tile.tileParser.SelectionStmtContext; @@ -312,11 +313,13 @@ public Statement visitTypeDefinition(TypeDefinitionContext ctx) { if (ctx.structDefinition() != null) { fields = new HashMap<>(); kind = TypeDefinition.Kind.STRUCT; + int offset = 0; 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(); int type_size = TypeResolver.resolveFieldTypeSize(type); - TypeDefinition.Field field = new TypeDefinition.Field(id, type, type_size); + TypeDefinition.Field field = new TypeDefinition.Field(id, type, type_size, offset); + offset += type_size; if (!fields.containsKey(id)) { fields.put(id, field); } else { @@ -466,10 +469,21 @@ public Statement visitWhileStmt(WhileStmtContext ctx) { @Override public Statement visitVariableAssignment(VariableAssignmentContext ctx) { String varId = ""; + List fieldIds = new ArrayList<>(); if (ctx.arrayIndexAccessorSetter() != null) { varId = ctx.arrayIndexAccessorSetter().IDENTIFIER().getText(); } else if (ctx.objectAccessor() != null) { varId = ctx.objectAccessor().IDENTIFIER(0).getText(); + ObjectAccessorContext oac = ctx.objectAccessor(); + if (oac.IDENTIFIER(1) != null) { + fieldIds.add(oac.IDENTIFIER(1).getText()); + } + while (oac.objectAccessor() != null) { + oac = oac.objectAccessor(); + fieldIds.add(oac.IDENTIFIER(0).getText()); + } + + Log.debug(fieldIds.toString()); } else { varId = ctx.IDENTIFIER().getText(); } @@ -487,7 +501,8 @@ public Statement visitVariableAssignment(VariableAssignmentContext ctx) { line = ctx.arrayIndexAccessorSetter().IDENTIFIER().getSymbol().getLine(); col = ctx.arrayIndexAccessorSetter().IDENTIFIER().getSymbol().getCharPositionInLine(); } else if (ctx.objectAccessor() != null) { - + line = ctx.objectAccessor().IDENTIFIER(0).getSymbol().getLine(); + col = ctx.objectAccessor().IDENTIFIER(0).getSymbol().getCharPositionInLine(); } else { line = ctx.IDENTIFIER().getSymbol().getLine(); col = ctx.IDENTIFIER().getSymbol().getCharPositionInLine(); @@ -520,6 +535,8 @@ public Statement visitVariableAssignment(VariableAssignmentContext ctx) { exprs.add(expr); } typeInfo = TypeResolver.resolveVariableDefArrayType(varTypeStr, exprType, dim); + } else if (ctx.objectAccessor() != null) { + typeInfo = TypeResolver.resolveVariableDefUserDefType(varTypeStr, exprType, fieldIds); } else { typeInfo = TypeResolver.resolveVariableDefType(varTypeStr, exprType); } diff --git a/src/tile/ast/expr/ObjectAccessor.java b/src/tile/ast/expr/ObjectAccessor.java index 5ce1cde..be058ef 100644 --- a/src/tile/ast/expr/ObjectAccessor.java +++ b/src/tile/ast/expr/ObjectAccessor.java @@ -33,9 +33,8 @@ private String genLoadCode(String generatedCode) { @Override public String generateTasm(String generatedCode) { int size = typeDefinition.getFields().get(fieldId).type_size; - int offset = 0; + int offset = typeDefinition.getFields().get(fieldId).offset; - // TODO: implement here generatedCode = genLoadCode(generatedCode); generatedCode += " deref ; dereferance\n"; generatedCode += " push " + offset + "\n"; @@ -46,7 +45,6 @@ public String generateTasm(String generatedCode) { @Override public String getType() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getType'"); + return typeDefinition.getFields().get(fieldId).type; } } diff --git a/src/tile/ast/stmt/TypeDefinition.java b/src/tile/ast/stmt/TypeDefinition.java index 7d6be4a..315c5c2 100644 --- a/src/tile/ast/stmt/TypeDefinition.java +++ b/src/tile/ast/stmt/TypeDefinition.java @@ -18,11 +18,13 @@ public static class Field { public String id; public String type; public int type_size; + public int offset; - public Field(String id, String type, int type_size) { + public Field(String id, String type, int type_size, int offset) { this.id = id; this.type = type; this.type_size = type_size; + this.offset = offset; } } diff --git a/src/tile/ast/stmt/VariableAssignment.java b/src/tile/ast/stmt/VariableAssignment.java index de0f683..20969e6 100644 --- a/src/tile/ast/stmt/VariableAssignment.java +++ b/src/tile/ast/stmt/VariableAssignment.java @@ -55,14 +55,29 @@ else if (typeInfo.var_type.equals("float") && typeInfo.expr_type.equals("int")) } } - if (typeInfo.info_array == null) { + if (typeInfo.info_array == null && typeInfo.info_object == null) { generatedCode += " "; if (isGlobal) { generatedCode += "gstore " + tasmIdx + " ; " + typeInfo.var_type + " " + varId + "\n"; } else { generatedCode += "store " + tasmIdx + " ; " + typeInfo.var_type + " " + varId + "\n"; } - } else { + } else if (typeInfo.info_object != null) { + + String lastFieldId = typeInfo.info_object.fieldIds.getLast(); + int type_size = typeInfo.info_object.fields.get(lastFieldId).type_size; + int offset = typeInfo.info_object.fields.get(lastFieldId).offset; + + if (isGlobal) { + generatedCode += " gload " + tasmIdx + "\n"; + } else { + generatedCode += " load " + tasmIdx + "\n"; + } + // FIXME: fix here hset created for arrays + generatedCode += " push " + offset + "\n"; + generatedCode += " push " + type_size + "\n"; + generatedCode += " hset\n"; + } else if (typeInfo.info_array != null) { if (isGlobal) { generatedCode += " gload " + tasmIdx + "\n"; } else { diff --git a/src/tile/ast/types/TypeResolver.java b/src/tile/ast/types/TypeResolver.java index d12e1bb..ae3d24e 100644 --- a/src/tile/ast/types/TypeResolver.java +++ b/src/tile/ast/types/TypeResolver.java @@ -55,6 +55,7 @@ public static class TypeInfoVariableDef { public boolean auto_cast = false; public String expr_type = null; public TypeInfoArray info_array = null; + public TypeInfoObject info_object = null; } public static class TypeInfoArray { @@ -62,6 +63,12 @@ public static class TypeInfoArray { public int element_size; } + public static class TypeInfoObject { + public String type; + public HashMap fields; + public List fieldIds; + } + public static boolean isNumericType(String type) { return (isIntType(type) || isFloatType(type)); } @@ -410,7 +417,7 @@ public static TypeInfoVariableDef resolveVariableDefType(String var_type, String public static TypeInfoVariableDef resolveVariableDefArrayType(String var_type, String expr_type, int reducedDim) { if (!isArrayType(var_type)) { - Log.error("it's not an array type"); + Log.error(var_type + " is not an array type"); return null; } TypeInfoVariableDef vd = new TypeInfoVariableDef(); @@ -426,6 +433,28 @@ public static TypeInfoVariableDef resolveVariableDefArrayType(String var_type, S return vd; } + public static TypeInfoVariableDef resolveVariableDefUserDefType(String var_type, String expr_type, List fieldIds) { + if (!isUserDefinedType(var_type)) { + Log.error(var_type + " is not a user defined type"); + return null; + } + TypeInfoVariableDef vd = new TypeInfoVariableDef(); + // TODO: check for auto cast + vd.expr_type = expr_type; + vd.var_type = var_type; + vd.result_type = var_type; + + // FIXME: make it for object inside object as well + TypeDefinition td = TypeResolver.userTypeDefs.get(var_type); + HashMap fields = td.getFields(); + + + vd.info_object = new TypeInfoObject(); + vd.info_object.fields = fields; + vd.info_object.fieldIds = fieldIds; + return vd; + } + public static TypeInfoVariableDef resolveVariableDefForFunctionArgs(String var_type) { TypeInfoVariableDef vd = new TypeInfoVariableDef(); vd.auto_cast = false; From b389d2bdd24c96e9398270379544eb0b9ff095ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Muhammed=20Yasinhan=20Ya=C5=9Far?= Date: Tue, 13 May 2025 08:21:03 +0300 Subject: [PATCH 6/7] randomness implemented for cherry * randomness is implemented for cherry position * cherry will not appear under the snake anymore --- examples/snake/snake.tile | 29 +++++++++++++++++++++-------- examples/tileraylib.tile | 1 + 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/examples/snake/snake.tile b/examples/snake/snake.tile index 2a1a454..c9bf0be 100644 --- a/examples/snake/snake.tile +++ b/examples/snake/snake.tile @@ -8,14 +8,22 @@ import "../tileraylib.tile"; screenWidth: int = 400; screenHeight: int = screenWidth; -func run_game(): void { - - prev_dirs: int[] = int[50]; - posx: float[] = float[50]; - posy: float[] = float[50]; - dirs: int[] = int[50]; +prev_dirs: int[] = int[50]; +posx: float[] = float[50]; +posy: float[] = float[50]; +dirs: int[] = int[50]; +snake_count: int = 1; + +func is_tile_empty(cherry_posx: float, cherry_posy: float): bool { + for (i: int = 0; i < snake_count; i++) { + if ((int)cherry_posx == (int)posx[i] && (int)cherry_posy == (int)posy[i]) { + return false; + } + } + return true; +} - snake_count: int = 1; +func run_game(): void { snake_step: int = screenWidth / 10; snake_size: int = snake_step; @@ -111,6 +119,11 @@ func run_game(): void { // randomly put the cherry again cherry_posx = GetRandomValue(0, 9) * snake_size; cherry_posy = GetRandomValue(0, 9) * snake_size; + // do not allow cherry to be appeared under snake! + while (!is_tile_empty(cherry_posx, cherry_posy)) { + cherry_posx = GetRandomValue(0, 9) * snake_size; + cherry_posy = GetRandomValue(0, 9) * snake_size; + } } } @@ -151,7 +164,7 @@ func main(argc: int): void { InitWindow(screenWidth, screenHeight, "Snake Game"); SetTargetFPS(60); // Set our game to run at 60 frames-per-second - SetRandomSeed(4642); + SetRandomSeed(GetTime() * 100); run_game(); diff --git a/examples/tileraylib.tile b/examples/tileraylib.tile index 8a34b8d..89bf999 100644 --- a/examples/tileraylib.tile +++ b/examples/tileraylib.tile @@ -11,6 +11,7 @@ native func EndDrawing(): cvoid; native func ClearBackground(color: cu32): cvoid; native func SetTargetFPS(fps: ci32): cvoid; native func GetFrameTime(): cf32; +native func GetTime(): cf64; native func DrawRectangle(posX: ci32, posY: ci32, width: ci32, height: ci32, color: cu32): cvoid; native func DrawCircle(posX: ci32, posY: ci32, radius: cf32, color: cu32): cvoid; native func DrawLine(ci32, ci32, ci32, ci32, cu32): cvoid; From f69aef841c54bc9368351dece03c52f176a75892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Muhammed=20Yasinhan=20Ya=C5=9Far?= Date: Mon, 19 May 2025 04:30:47 +0300 Subject: [PATCH 7/7] unary operator '!' bug fix for primary expr identifiers --- src/tile/AntlrToExpression.java | 4 ++++ src/tile/ast/expr/PrimaryExpression.java | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/tile/AntlrToExpression.java b/src/tile/AntlrToExpression.java index 137d013..e71c431 100644 --- a/src/tile/AntlrToExpression.java +++ b/src/tile/AntlrToExpression.java @@ -468,6 +468,10 @@ public Expression visitUnaryExpression(UnaryExpressionContext ctx) { if (!(type.equals("int") || type.equals("float"))) { Log.error("'+' and '-' prefixes cannot go before any non-numeric type!"); } + } else if (unaryOp.equals("!")) { + if (!type.equals("bool")) { + Log.error("'" + unaryOp + "' operator cannot go before this type: " + type); + } } } else if (ctx.incDecOperator() != null) { diff --git a/src/tile/ast/expr/PrimaryExpression.java b/src/tile/ast/expr/PrimaryExpression.java index d8fefa4..09cde7a 100644 --- a/src/tile/ast/expr/PrimaryExpression.java +++ b/src/tile/ast/expr/PrimaryExpression.java @@ -77,6 +77,14 @@ private String generateTasmForPrimitive(String generatedCode) { } } } + if (isUnaryNotNull) { + if (unaryOp.equals("!")) { + if (type.equals("bool")) { + generatedCode += " "; + generatedCode += "not" + "; !\n"; + } + } + } if (isUnaryNotNull) { // TODO: solve the "load"ing the value problem for each iteration unary operator ++ or -- called. It fills stack! (use pop or don't generate the load below under some conditions!)