From 262fc29fc2ab57077435c8495b312d27f8b8b81c Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Mon, 22 Apr 2024 19:29:06 +0200 Subject: [PATCH 01/94] God start --- .../cs_24_sw_4_16/carl/CstToAst/CstToAst.java | 34 -------- .../java/dk/aau/cs_24_sw_4_16/carl/Main.java | 33 +++++++- .../carl/Semantic_A/SemanticAnalyzer.java | 83 +++++++++++++++++++ .../cs_24_sw_4_16/carl/Semantic_A/Type.java | 30 +++++++ 4 files changed, 143 insertions(+), 37 deletions(-) delete mode 100644 src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAst.java create mode 100644 src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java create mode 100644 src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Type.java diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAst.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAst.java deleted file mode 100644 index 9dd18ce..0000000 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAst.java +++ /dev/null @@ -1,34 +0,0 @@ -package dk.aau.cs_24_sw_4_16.carl.CstToAst; - - -import dk.aau.cs_24_sw_4_16.carl.CARLLexer; -import dk.aau.cs_24_sw_4_16.carl.CARLParser; -import dk.aau.cs_24_sw_4_16.carl.Interpreter.Interpreter; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.tree.ParseTree; - -import java.io.FileInputStream; -import java.io.IOException; - -public class CstToAst { - - public static void main(String[] args) throws IOException { - try { - FileInputStream fileInput = new FileInputStream("test.carl"); - - CARLLexer lexer = new CARLLexer(CharStreams.fromStream(fileInput)); - CommonTokenStream tokens = new CommonTokenStream(lexer); - CARLParser parser = new CARLParser(tokens); - - ParseTree tree = parser.program(); - CstToAstVisitor visitor = new CstToAstVisitor(); - AstNode astRoot = visitor.visit(tree); - Interpreter inter = new Interpreter(); - inter.visit(astRoot); - } - catch (Exception e){ - System.out.println(e.toString()); - } - } -} diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index a81afc1..119609f 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -1,6 +1,5 @@ package dk.aau.cs_24_sw_4_16.carl; - import dk.aau.cs_24_sw_4_16.carl.CstToAst.AstNode; import dk.aau.cs_24_sw_4_16.carl.CstToAst.CstToAstVisitor; import dk.aau.cs_24_sw_4_16.carl.Interpreter.Interpreter; @@ -9,24 +8,52 @@ import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; +import dk.aau.cs_24_sw_4_16.carl.Semantic_A.SemanticAnalyzer; import java.io.FileInputStream; public class Main { public static void main(String... args) { try { + /* + * Java libary takes in filepath, reads file into memory. Can now be acced + * throught identifier fileinput + */ FileInputStream fileInput = new FileInputStream("test.carl"); - + // CARLLexer is a generated lexer class for the CARL language. + // It tokenizes the input stream (breaks the input into meaningful pieces called + // tokens). CARLLexer lexer = new CARLLexer(CharStreams.fromStream(fileInput)); + // CommonTokenStream is a class from ANTLR that is used to store the tokens + // generated by the lexer. + // These tokens are used by the parser to create a parse tree. CommonTokenStream tokens = new CommonTokenStream(lexer); + // CARLParser is a generated parser class for the CARL language. + // It takes a stream of tokens and builds a parse tree based on the grammar of + // the language. CARLParser parser = new CARLParser(tokens); + // The program() method is a part of the parser that starts the parsing process. + // It returns a parse tree representing the entire input file. + ParseTree tree = parser.program();// Her stopper det som Antler har lavet. + - ParseTree tree = parser.program(); + // CstToAstVisitor is a visitor class that converts the parse tree (CST) into an abstract syntax tree (AST). + // This is typically used to simplify and optimize the tree structure for further processing. CstToAstVisitor visitor = new CstToAstVisitor(); + // The visit method walks the parse tree and constructs the AST AstNode astRoot = visitor.visit(tree); + + + SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer(); + semanticAnalyzer.analyze(astRoot); + + // Interpreter is a class that can traverse the AST and interpret or execute the program based on the AST. Interpreter inter = new Interpreter(); + inter.visit(astRoot); } catch (Exception e) { + // Catches any exception that occurs within the try block. + // Prints the string representation of the exception to standard output. System.out.println(e.toString()); } } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java new file mode 100644 index 0000000..8162b39 --- /dev/null +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java @@ -0,0 +1,83 @@ +package dk.aau.cs_24_sw_4_16.carl.Semantic_A; + +import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; +// ... (other necessary imports) + +public class SemanticAnalyzer { + + public void analyze(AstNode root) throws SemanticException { + if (root != null) { + visit(root); + } + } + + private void visit(AstNode node) throws SemanticException { + // Implement type checking logic for each relevant node type + if (node instanceof BinaryExpressionNode) { + checkBinaryExpression((BinaryExpressionNode) node); + } + // You can add more checks here for different types of nodes as needed + + // Recursively visit all children of the current node + for (AstNode child : node.getChildren()) { + visit(child); + } + } + + private void checkBinaryExpression(BinaryExpressionNode node) throws SemanticException { + AstNode left = node.getLeft(); + AstNode right = node.getRight(); + + // Retrieve the types of the left and right operands + Type leftType = getType(left); + Type rightType = getType(right); + + // Perform type compatibility check for the specific binary operation + if (!isOperationTypeCompatible(leftType, rightType, node.getOperator())) { + throw new SemanticException("Type mismatch for operator '" + node.getOperator() + "': " + leftType + " and " + rightType); + } + + // If necessary, set the type for the binary expression itself + // e.g., node.setType(resultingTypeOfOperation(leftType, rightType)); + } + + // Check if the operation is compatible with the given types + private boolean isOperationTypeCompatible(Type leftType, Type rightType, String operator) { + // Example for addition operation + if (operator.equals("+")) { + // Let's assume for simplicity that we can only add numbers + if (leftType == Type.INT && rightType == Type.INT) { + return true; + } + // Add more rules as per your language specification + } + // Include checks for other operators + + return false; // Default to false if not compatible + } + + // Retrieve the type of a given AST node + private Type getType(AstNode node) { + if (node instanceof IntNode) { + return Type.INT; + } else if (node instanceof FloatNode) { + return Type.FLOAT; + } else if (node instanceof StringNode) { + return Type.STRING; + } else if (node instanceof VariableReferenceNode) { + // Lookup variable type in symbol table + // Assuming you have a method to get the variable type + // return getVariableTypeFromSymbolTable(((VariableReferenceNode) node).getName()); + } + // Handle more node types as necessary + + return Type.UNKNOWN; // Or any other default you want to assign + } + + // Define an exception class for semantic errors + public static class SemanticException extends Exception { + public SemanticException(String message) { + super(message); + } + } +} diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Type.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Type.java new file mode 100644 index 0000000..37d64cc --- /dev/null +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Type.java @@ -0,0 +1,30 @@ +package dk.aau.cs_24_sw_4_16.carl.Semantic_A; + +public enum Type { + INT("int"), // Integer type + FLOAT("float"), // Floating-point type + STRING("string"), // String type + BOOLEAN("boolean"), // Boolean type + VOID("void"), // Type for functions that don't return a value + // ... add other types as needed + UNKNOWN("unknown"); // Used for uninitialized or error states + + private final String typeName; + + Type(String typeName) { + this.typeName = typeName; + } + + // This method returns the type name as a string. + public String getTypeName() { + return typeName; + } + + // This method might be used to check if two types are compatible. + // For simplicity, it's just checking for equality here. + public boolean isCompatible(Type otherType) { + return this == otherType; + } + + // ... you can add more methods to handle type-specific logic +} \ No newline at end of file From 0d451e51bef6e1803eae4e4258bb29b68e0a14e4 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Tue, 23 Apr 2024 17:34:25 +0200 Subject: [PATCH 02/94] Abselut copy paste, form visitor --- .../carl/Semantic_A/SemanticAnalyzer.java | 23 +- .../carl/Semantic_A/Visitor.java | 326 ++++++++++++++++++ 2 files changed, 331 insertions(+), 18 deletions(-) create mode 100644 src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java index 8162b39..8dd1a03 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java @@ -1,30 +1,17 @@ package dk.aau.cs_24_sw_4_16.carl.Semantic_A; import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; -// ... (other necessary imports) - public class SemanticAnalyzer { + public boolean printTest =true; public void analyze(AstNode root) throws SemanticException { - if (root != null) { - visit(root); - } + } - private void visit(AstNode node) throws SemanticException { - // Implement type checking logic for each relevant node type - if (node instanceof BinaryExpressionNode) { - checkBinaryExpression((BinaryExpressionNode) node); - } - // You can add more checks here for different types of nodes as needed - // Recursively visit all children of the current node - for (AstNode child : node.getChildren()) { - visit(child); - } - } - private void checkBinaryExpression(BinaryExpressionNode node) throws SemanticException { + + private void checkBinaryExpression(BinaryOperatorNode node) throws SemanticException { AstNode left = node.getLeft(); AstNode right = node.getRight(); @@ -64,7 +51,7 @@ private Type getType(AstNode node) { return Type.FLOAT; } else if (node instanceof StringNode) { return Type.STRING; - } else if (node instanceof VariableReferenceNode) { + } else if (node instanceof IdentifierNode) { // Lookup variable type in symbol table // Assuming you have a method to get the variable type // return getVariableTypeFromSymbolTable(((VariableReferenceNode) node).getName()); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java new file mode 100644 index 0000000..1875391 --- /dev/null +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java @@ -0,0 +1,326 @@ +package dk.aau.cs_24_sw_4_16.carl.Semantic_A; + +import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; +import java.util.*; +import dk.aau.cs_24_sw_4_16.carl.Interpreter.InbuildClasses;; + +public class Visitor { + HashMap fTable; + HashMap vTable; + Stack> scopes; + Deque activeScope; + + public AstNode visit(AstNode node) { + if (node instanceof ProgramNode) { + return visit((ProgramNode) node); + } else if (node instanceof StatementNode) { + return visit((StatementNode) node); + } else if (node instanceof ExpressionNode) { + return visit((ExpressionNode) node); + } + return node; + } + + public AstNode visit(StatementNode node) { + if (node.getNode() instanceof AssignmentNode) { + visit((AssignmentNode) node.getNode()); + } else if (node.getNode() instanceof VariableDeclarationNode) { + visit((VariableDeclarationNode) node.getNode()); + } else if (node.getNode() instanceof FunctionCallNode) { + return visit((FunctionCallNode) node.getNode()); + } else if (node.getNode() instanceof FunctionDefinitionNode) { + return visit((FunctionDefinitionNode) node.getNode()); + } else if (node.getNode() instanceof WhileLoopNode) { + return visit((WhileLoopNode) node.getNode()); + } else if (node.getNode() instanceof IfStatementNode) { + visit((IfStatementNode) node.getNode()); + } else if (node.getNode() instanceof BinaryOperatorNode) { + visit((BinaryOperatorNode) node.getNode()); + if (true) { + System.out.println("Hej jeg kommer int i interpriter binaryoperator"); + } + } else if (node.getNode() instanceof ReturnStatementNode) { + return visit((ReturnStatementNode) node.getNode()); + } + return null; + } + + public AstNode visit(ReturnStatementNode node) { + return node; + } + + public void visit(IfStatementNode node) { + HashMap localTable = new HashMap<>(); + scopes.add(localTable); + boolean visited = false; + for (int i = 0; i < node.getExpressions().size(); i++) { + AstNode toCheck = node.getExpressions().get(i).getNode(); + if (node.getExpressions().get(i).getNode() instanceof IdentifierNode) { + toCheck = getVariable((IdentifierNode) node.getExpressions().get(i).getNode()); + } else if (node.getExpressions().get(i).getNode() instanceof RelationsAndLogicalOperatorNode) { + toCheck = visit((RelationsAndLogicalOperatorNode) node.getExpressions().get(i).getNode()); + } + if (toCheck instanceof BoolNode && ((BoolNode) toCheck).getValue()) { + visit(node.getBlocks().get(i)); + visited = true; + break; + } + } + if (!visited && node.getExpressions().size() < node.getBlocks().size()) { + visit(node.getBlocks().get(node.getBlocks().size() - 1)); + } + scopes.remove(localTable); + } + + public AstNode getVariable(IdentifierNode node) { + // for (HashMap vTable : scopes) { + if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { + return scopes.getFirst().get(node.getIdentifier().toString()); + } + + for (int i = activeScope.getLast(); i < scopes.size(); i++) { + if (scopes.get(i).containsKey(node.getIdentifier().toString())) { + return scopes.get(i).get(node.getIdentifier().toString()); + } + } + throw new RuntimeException("could not find the variable " + node.getIdentifier()); + } + + public void visit(AssignmentNode node) { + + for (HashMap vTable : scopes) { + if (vTable.containsKey(node.getIdentifier().toString())) { + AstNode nodeToChange = vTable.get(node.getIdentifier().toString()); + AstNode toChange = node.getValue(); + if (toChange instanceof BinaryOperatorNode) { + toChange = visit((BinaryOperatorNode) toChange); + } + if (toChange instanceof FunctionCallNode) { + toChange = visit((FunctionCallNode) toChange); + } + if (toChange instanceof IdentifierNode) { + toChange = getVariable((IdentifierNode) toChange); + } + if (node.getValue() instanceof RelationsAndLogicalOperatorNode) { + toChange = visit((RelationsAndLogicalOperatorNode) toChange); + } + AstNode finalToChange = toChange; + switch (nodeToChange) { + case IntNode intNode when finalToChange instanceof IntNode -> + intNode.setValue(((IntNode) finalToChange).getValue()); + case FloatNode floatNode when finalToChange instanceof FloatNode -> + floatNode.setValue(((FloatNode) finalToChange).getValue()); + case StringNode stringNode when finalToChange instanceof StringNode -> + stringNode.setValue(((StringNode) finalToChange).getValue()); + case BoolNode boolNode when finalToChange instanceof BoolNode -> + boolNode.setValue(((BoolNode) finalToChange).getValue()); + case null, default -> throw new RuntimeException("Type mismatch"); + } + return; + } + } + + throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); + } + + public void visit(VariableDeclarationNode node) { + boolean found = false; + if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { + found = true; + } + + for (int i = activeScope.getLast(); i < scopes.size(); i++) { + if (scopes.get(i).containsKey(node.getIdentifier().toString())) { + found = true; + } + } + if (!found) { + + AstNode toChange = node.getValue(); + if (node.getValue() instanceof BinaryOperatorNode) { + toChange = visit((BinaryOperatorNode) node.getValue()); + scopes.getLast().put(node.getIdentifier().toString(), toChange); + } else if (toChange instanceof IdentifierNode) { + for (HashMap vTable : scopes) { + if (vTable.containsKey(toChange.toString())) { + scopes.getLast().put(node.getIdentifier().toString(), vTable.get(toChange.toString())); + } + } + } else { + scopes.getLast().put(node.getIdentifier().toString(), toChange); + } + + } else { + throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); + } + } + + public AstNode visit(TypeNode node) { + return node; + } + + public AstNode visit(BoolNode node) { + return node; + } + + public AstNode visit(IntNode node) { + return node; + } + + public AstNode visit(FloatNode node) { + return node; + } + + public AstNode visit(ProgramNode node) { + for (AstNode statement : node.getStatements()) { + visit(statement); + } + return node; + } + + public AstNode visit(FunctionCallNode node) { + if (node.getFunctionName().toString().equals("print")) { + InbuildClasses.print(node, scopes, activeScope); + } else { + HashMap localTable = new HashMap<>(); + scopes.add(localTable); + activeScope.add(scopes.size() - 1); + + if (fTable.containsKey(node.getFunctionName().toString())) { + FunctionDefinitionNode function = fTable.get(node.getFunctionName().toString()); + List arguments = function.getArguments().getParameters(); + for (int i = 0; i < function.getArguments().getParameters().size(); i++) { + visit(new VariableDeclarationNode(arguments.get(i).getIdentifier(), arguments.get(i).getType(), + node.getArgument(i))); + } + AstNode test = visit(function.getBlock()); + + if (test instanceof ReturnStatementNode) { + AstNode returnValue = ((ReturnStatementNode) test).getReturnValue(); + if (returnValue instanceof IdentifierNode) { + returnValue = getVariable((IdentifierNode) returnValue); + } + scopes.remove(localTable); + activeScope.removeLast(); + if (function.getReturnType().getType().equals("void")) { + if (returnValue != null) { + throw new RuntimeException( + "cannot return a value in void function call or have code after return statement"); + } + return node; + } + + return returnValue; + } + } + } + return node; + } + + public AstNode visit(BlockNode node) { + for (AstNode statement : node.getStatements()) { + + if (((StatementNode) statement).getNode() instanceof ReturnStatementNode) { + return visit((StatementNode) statement); + } else { + visit((StatementNode) statement); + } + } + return node; + } + + public AstNode visit(ExpressionNode node) { + if (node.getNode() instanceof FunctionCallNode) { + return visit((FunctionCallNode) node.getNode()); + } else if (node.getNode() instanceof RelationsAndLogicalOperatorNode) { + return visit((RelationsAndLogicalOperatorNode) node.getNode()); + } else if (node.getNode() instanceof BinaryOperatorNode) { + return visit((BinaryOperatorNode) node.getNode()); + } + return node; + } + + public AstNode visit(FunctionDefinitionNode node) { + if (!fTable.containsKey(node.getIdentifier().toString())) { + fTable.put(node.getIdentifier().toString(), node); + } else { + throw new RuntimeException("function " + node.getIdentifier() + " already exists"); + } + return node; + } + + public AstNode visit(BinaryOperatorNode node) { + if (true) { + System.out.println("Hej jeg kommer int i binarty2"); + } + AstNode left = node.getLeft(); + AstNode right = node.getRight(); + if (left instanceof IdentifierNode) { + left = getVariable((IdentifierNode) left); + } else if (left instanceof BinaryOperatorNode) { + left = visit((BinaryOperatorNode) left); + } + if (right instanceof IdentifierNode) { + right = getVariable((IdentifierNode) right); + } else if (right instanceof BinaryOperatorNode) { + right = visit((BinaryOperatorNode) right); + } + + if (left instanceof IntNode && right instanceof IntNode) { + return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); + } else if (left instanceof FloatNode && right instanceof FloatNode) { + return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); + } + throw new RuntimeException("BinaryOperator not implemented clause"); + } + + public AstNode visit(RelationsAndLogicalOperatorNode node) { + AstNode left = node.getLeft(); + AstNode right = node.getRight(); + if (left instanceof IdentifierNode) { + left = getVariable((IdentifierNode) left); + } else if (left instanceof RelationsAndLogicalOperatorNode) { + left = visit((RelationsAndLogicalOperatorNode) left); + } + if (right instanceof IdentifierNode) { + right = getVariable((IdentifierNode) right); + } else if (right instanceof RelationsAndLogicalOperatorNode) { + right = visit((RelationsAndLogicalOperatorNode) right); + } + if (left instanceof IntNode && right instanceof IntNode) { + return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); + } else if (left instanceof FloatNode && right instanceof FloatNode) { + return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); + } else if (left instanceof BoolNode && right instanceof BoolNode) { + return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); + } + throw new RuntimeException("RelationsAndLogicalOperator not implemented clause"); + } + + public AstNode visit(WhileLoopNode node) { + AstNode toCheck = (node.getExpression()).getNode(); + if (toCheck instanceof IdentifierNode) { + toCheck = getVariable((IdentifierNode) node.getExpression().getNode()); + } else if (toCheck instanceof RelationsAndLogicalOperatorNode) { + toCheck = visit((RelationsAndLogicalOperatorNode) toCheck); + } + while ((toCheck instanceof BoolNode)) { + if (((BoolNode) toCheck).getValue()) { + HashMap localTable = new HashMap<>(); + scopes.add(localTable); + visit(node.getBlock()); + toCheck = visit(node.getExpression().getNode()); + if (toCheck instanceof IdentifierNode) { + toCheck = getVariable((IdentifierNode) node.getExpression().getNode()); + } else if (toCheck instanceof RelationsAndLogicalOperatorNode) { + toCheck = visit((RelationsAndLogicalOperatorNode) toCheck); + } + scopes.remove(localTable); + } else { + return node; + } + + } + throw new RuntimeException("Did not get into while statement"); + } +} From 814073dae41b9b8db1400cff0eca956e5d9c2560 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:39:39 +0200 Subject: [PATCH 03/94] Har fundet ud af hvad jeg skal --- .../carl/Semantic_A/SemanticAnalyzer.java | 156 +++++++++++++++++- test.carl | 4 + 2 files changed, 152 insertions(+), 8 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java index 8dd1a03..57b2c07 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java @@ -1,16 +1,151 @@ package dk.aau.cs_24_sw_4_16.carl.Semantic_A; import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; + public class SemanticAnalyzer { - public boolean printTest =true; + public boolean printTest = true; + public void analyze(AstNode root) throws SemanticException { - + if (printTest) { + System.out.println("Hej jeg kommer her ind"); + } + + if (root != null) { + visit(root); + } + } + + private void visit(AstNode node) throws SemanticException { + if (node instanceof ProgramNode) { + visitProgram((ProgramNode) node); + if (printTest) { + System.out.println("Hej jeg kommer ind i programnode"); + } + } else if (node instanceof BinaryOperatorNode) { + visitBinaryOperator((BinaryOperatorNode) node); + if (printTest) { + System.out.println("Hej jeg kommer ind i binary"); + } + } else if (node instanceof StatementNode) { + visitStatement((StatementNode) node); + if (printTest) { + System.out.println("Hej jeg kommer ind i statement"); + } + } else if (node instanceof ExpressionNode) { + visitExpression((ExpressionNode) node); + if (printTest) { + System.out.println("Hej jeg kommer ind i expression"); + } + } else if (node instanceof BlockNode) { + visitBlock((BlockNode) node); + if (printTest) { + System.out.println("Hej jeg kommer ind i block"); + } + } else if (node instanceof IfStatementNode) { + visitIfStatement((IfStatementNode) node); + if (printTest) { + System.out.println("Hej jeg kommer ind i if statement"); + } + } else if (node instanceof WhileLoopNode) { + visitWhileLoop((WhileLoopNode) node); + if (printTest) { + System.out.println("Hej jeg kommer ind i while loop"); + } + } else if (node instanceof FunctionDefinitionNode) { + visitFunctionDefinition((FunctionDefinitionNode) node); + if (printTest) { + System.out.println("Hej jeg kommer ind i function definition"); + } + } else if (node instanceof ReturnStatementNode) { + visitReturnStatement((ReturnStatementNode) node); + if (printTest) { + System.out.println("Hej jeg kommer ind i return statement"); + } + } else if (node instanceof FunctionCallNode) { + visitFunctionCall((FunctionCallNode) node); + if (printTest) { + System.out.println("Hej jeg kommer ind i function call"); + } + } else if (node instanceof VariableDeclarationNode) { + visitVariableDeclaration((VariableDeclarationNode) node); + if (printTest) { + System.out.println("Hej jeg kommer ind i variable"); + } + } + // Add more as necessary + } + + private void visitVariableDeclaration(VariableDeclarationNode node) throws SemanticException { + System.out.println(node.toString()); + visit(node.getValue()); + } + + private void visitProgram(ProgramNode node) throws SemanticException { + for (AstNode statement : node.getStatements()) { + visit(statement); + } + } + + private void visitStatement(StatementNode node) throws SemanticException { + // Assuming StatementNode holds a single statement or compound statements + visit(node.getNode()); + } + + private void visitIfStatement(IfStatementNode node) throws SemanticException { + // visit(node.getCondition()); + // visit(node.getThenBlock()); + // if (node.getElseBlock() != null) { + // visit(node.getElseBlock()); + // } + } + + private void visitWhileLoop(WhileLoopNode node) throws SemanticException { + // visit(node.getCondition()); + // visit(node.getBody()); + } + + private void visitFunctionDefinition(FunctionDefinitionNode node) throws SemanticException { + // for (ParameterNode param : node.getParameters()) { + // visit(param); + // } + // visit(node.getBody()); + } + + private void visitReturnStatement(ReturnStatementNode node) throws SemanticException { + // if (node.getExpression() != null) { + // visit(node.getExpression()); + // } + } + + private void visitFunctionCall(FunctionCallNode node) throws SemanticException { + // for (ExpressionNode argument : node.getArguments()) { + // visit(argument); + // } } + private void visitExpression(ExpressionNode node) throws SemanticException { + // Assuming ExpressionNode wraps an expression + visit(node.getNode()); + } + private void visitBlock(BlockNode node) throws SemanticException { + for (AstNode statement : node.getStatements()) { + visit(statement); + } + } + + private void visitBinaryOperator(BinaryOperatorNode node) throws SemanticException { + // Specific checks for BinaryOperatorNode + checkBinaryExpression(node); + if (printTest) { + System.out.println("Hej jeg kommer int i visitbinary opertor"); + } + // Recursively visit left and right children + visit(node.getLeft()); + visit(node.getRight()); + } - private void checkBinaryExpression(BinaryOperatorNode node) throws SemanticException { AstNode left = node.getLeft(); AstNode right = node.getRight(); @@ -18,10 +153,14 @@ private void checkBinaryExpression(BinaryOperatorNode node) throws SemanticExcep // Retrieve the types of the left and right operands Type leftType = getType(left); Type rightType = getType(right); - - // Perform type compatibility check for the specific binary operation - if (!isOperationTypeCompatible(leftType, rightType, node.getOperator())) { - throw new SemanticException("Type mismatch for operator '" + node.getOperator() + "': " + leftType + " and " + rightType); + try { + // Perform type compatibility check for the specific binary operation + if (!isOperationTypeCompatible(leftType, rightType, node.getOperator())) { + throw new SemanticException( + "Type mismatch for operator '" + node.getOperator() + "': " + leftType + " and " + rightType); + } + } catch (Exception e) { + // TODO: handle exception } // If necessary, set the type for the binary expression itself @@ -54,7 +193,8 @@ private Type getType(AstNode node) { } else if (node instanceof IdentifierNode) { // Lookup variable type in symbol table // Assuming you have a method to get the variable type - // return getVariableTypeFromSymbolTable(((VariableReferenceNode) node).getName()); + // return getVariableTypeFromSymbolTable(((VariableReferenceNode) + // node).getName()); } // Handle more node types as necessary diff --git a/test.carl b/test.carl index adcef95..f5eaacb 100644 --- a/test.carl +++ b/test.carl @@ -10,6 +10,10 @@ print(c,"My Second C") c = (5 + d) * 5 c = 3 + (d + 5) +var p : int = c + y + +print(p, "CARLS PRINT" ) + while d <= 5{ print(d) var b2 : int = d From 3a84f0c68c8294a89ce2c53e53ca3c00273cd146 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Wed, 24 Apr 2024 11:45:51 +0200 Subject: [PATCH 04/94] Slow progress but i am working on it, --- .vscode/settings.json | 3 +++ .../carl/Semantic_A/SemanticAnalyzer.java | 6 +++++- .../aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java | 12 ++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c995aa5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.debug.settings.onBuildFailureProceed": true +} \ No newline at end of file diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java index 57b2c07..b723928 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java @@ -1,7 +1,6 @@ package dk.aau.cs_24_sw_4_16.carl.Semantic_A; import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; - public class SemanticAnalyzer { public boolean printTest = true; @@ -10,12 +9,17 @@ public void analyze(AstNode root) throws SemanticException { if (printTest) { System.out.println("Hej jeg kommer her ind"); } + System.out.println("Her starter visitor class"); + Visitor visitor = new Visitor(); + visitor.visit(root); + System.out.println("Her stopper visitor class"); if (root != null) { visit(root); } } + private void visit(AstNode node) throws SemanticException { if (node instanceof ProgramNode) { visitProgram((ProgramNode) node); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java index 1875391..59742fc 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java @@ -10,8 +10,20 @@ public class Visitor { Stack> scopes; Deque activeScope; + boolean printyes = true; + public AstNode visit(AstNode node) { if (node instanceof ProgramNode) { + if (printyes) { + System.out.println("Hej jeg kommer int i visitor"); + } + fTable = new HashMap<>(); + vTable = new HashMap<>(); + scopes = new Stack<>(); + activeScope = new ArrayDeque<>(); + activeScope.push(0); + scopes.add(vTable); + return visit((ProgramNode) node); } else if (node instanceof StatementNode) { return visit((StatementNode) node); From 013f635ceb9e155c132ce68e75b53c89a1802cba Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Wed, 24 Apr 2024 17:38:33 +0200 Subject: [PATCH 05/94] Before i ruin everythin --- .../carl/Interpreter/Interpreter.java | 2 +- .../java/dk/aau/cs_24_sw_4_16/carl/Main.java | 2 +- .../carl/Semantic_A/Visitor.java | 91 ++++++++++--------- test.carl | 6 +- 4 files changed, 54 insertions(+), 47 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java index 062c5f4..e2ad0df 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java @@ -270,7 +270,7 @@ public AstNode visit(BinaryOperatorNode node) { } else if (right instanceof BinaryOperatorNode) { right = visit((BinaryOperatorNode) right); } - + if (left instanceof IntNode && right instanceof IntNode) { return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); } else if (left instanceof FloatNode && right instanceof FloatNode) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index 119609f..8285feb 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -42,7 +42,7 @@ public static void main(String... args) { CstToAstVisitor visitor = new CstToAstVisitor(); // The visit method walks the parse tree and constructs the AST AstNode astRoot = visitor.visit(tree); - + System.out.println(astRoot); SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer(); semanticAnalyzer.analyze(astRoot); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java index 59742fc..0f59902 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java @@ -5,13 +5,13 @@ import dk.aau.cs_24_sw_4_16.carl.Interpreter.InbuildClasses;; public class Visitor { - HashMap fTable; - HashMap vTable; - Stack> scopes; - Deque activeScope; + HashMap fTable; // function table, identifier(x) og node + HashMap vTable;// variable table, identifier(x) og node(int) + Stack> scopes; // scope table, variable identifier(x) og node + Deque activeScope;// Hvilket scope vi er i nu + + boolean printyes = true;// ! SLET SENERE - boolean printyes = true; - public AstNode visit(AstNode node) { if (node instanceof ProgramNode) { if (printyes) { @@ -62,13 +62,15 @@ public AstNode visit(ReturnStatementNode node) { } public void visit(IfStatementNode node) { - HashMap localTable = new HashMap<>(); - scopes.add(localTable); + HashMap localTable = new HashMap<>(); // ny lokalt value table + scopes.add(localTable); // Tilføjer det til stacken med scopes boolean visited = false; - for (int i = 0; i < node.getExpressions().size(); i++) { + for (int i = 0; i < node.getExpressions().size(); i++) { // Hver expression er en if statement. Ligesom hver + // block er til den if statement AstNode toCheck = node.getExpressions().get(i).getNode(); if (node.getExpressions().get(i).getNode() instanceof IdentifierNode) { - toCheck = getVariable((IdentifierNode) node.getExpressions().get(i).getNode()); + toCheck = getVariable((IdentifierNode) node.getExpressions().get(i).getNode());// Hvis det er x så giv + // mig xnode } else if (node.getExpressions().get(i).getNode() instanceof RelationsAndLogicalOperatorNode) { toCheck = visit((RelationsAndLogicalOperatorNode) node.getExpressions().get(i).getNode()); } @@ -86,13 +88,13 @@ public void visit(IfStatementNode node) { public AstNode getVariable(IdentifierNode node) { // for (HashMap vTable : scopes) { - if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { - return scopes.getFirst().get(node.getIdentifier().toString()); + if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { // Tester om x er der, ev til bool + return scopes.getFirst().get(node.getIdentifier().toString());// i scope, giv mig x node } - for (int i = activeScope.getLast(); i < scopes.size(); i++) { + for (int i = activeScope.getLast(); i < scopes.size(); i++) {// for at gå igennem hvert scope og tjekke for x if (scopes.get(i).containsKey(node.getIdentifier().toString())) { - return scopes.get(i).get(node.getIdentifier().toString()); + return scopes.get(i).get(node.getIdentifier().toString());// i i scope, giv mig x node } } throw new RuntimeException("could not find the variable " + node.getIdentifier()); @@ -101,19 +103,19 @@ public AstNode getVariable(IdentifierNode node) { public void visit(AssignmentNode node) { for (HashMap vTable : scopes) { - if (vTable.containsKey(node.getIdentifier().toString())) { - AstNode nodeToChange = vTable.get(node.getIdentifier().toString()); - AstNode toChange = node.getValue(); + if (vTable.containsKey(node.getIdentifier().toString())) { // tjek if variable x is scopes bool + AstNode nodeToChange = vTable.get(node.getIdentifier().toString());// retunere node + AstNode toChange = node.getValue(); // Højre side af assignmen x= tochange vil retunere node if (toChange instanceof BinaryOperatorNode) { - toChange = visit((BinaryOperatorNode) toChange); + toChange = visit((BinaryOperatorNode) toChange); // if x= 20+20 } if (toChange instanceof FunctionCallNode) { - toChange = visit((FunctionCallNode) toChange); + toChange = visit((FunctionCallNode) toChange); // if x= functioncall(10) } if (toChange instanceof IdentifierNode) { - toChange = getVariable((IdentifierNode) toChange); + toChange = getVariable((IdentifierNode) toChange); // if x = y } - if (node.getValue() instanceof RelationsAndLogicalOperatorNode) { + if (node.getValue() instanceof RelationsAndLogicalOperatorNode) { // if x= 10<5 toChange = visit((RelationsAndLogicalOperatorNode) toChange); } AstNode finalToChange = toChange; @@ -137,32 +139,33 @@ public void visit(AssignmentNode node) { public void visit(VariableDeclarationNode node) { boolean found = false; - if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { + if (scopes.getFirst().containsKey(node.getIdentifier().toString())) {// finder x i scope FY FY found = true; } - for (int i = activeScope.getLast(); i < scopes.size(); i++) { + for (int i = activeScope.getLast(); i < scopes.size(); i++) {// finder x i et scope FY FY if (scopes.get(i).containsKey(node.getIdentifier().toString())) { found = true; } } - if (!found) { - - AstNode toChange = node.getValue(); - if (node.getValue() instanceof BinaryOperatorNode) { - toChange = visit((BinaryOperatorNode) node.getValue()); - scopes.getLast().put(node.getIdentifier().toString(), toChange); - } else if (toChange instanceof IdentifierNode) { - for (HashMap vTable : scopes) { - if (vTable.containsKey(toChange.toString())) { + if (!found) { // kunne ikke finde x i scope så kan gemme den + + AstNode toChange = node.getValue(); // x=value value = node eller 5 + if (node.getValue() instanceof BinaryOperatorNode) { // hvis x=2+2 + toChange = visit((BinaryOperatorNode) node.getValue()); // Henter type node efter operation node + scopes.getLast().put(node.getIdentifier().toString(), toChange); // Her sætter vi x til type node i + // scope hash map + } else if (toChange instanceof IdentifierNode) { // Vis x=y + for (HashMap vTable : scopes) {// For hvert scope skal vi prøve at finde variable + if (vTable.containsKey(toChange.toString())) {// Vis vi finder den i et scope scopes.getLast().put(node.getIdentifier().toString(), vTable.get(toChange.toString())); } } } else { - scopes.getLast().put(node.getIdentifier().toString(), toChange); + scopes.getLast().put(node.getIdentifier().toString(), toChange); // case hvor x=4 } - } else { + } else { // Fy fy den findes allerede throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); } } @@ -261,24 +264,26 @@ public AstNode visit(FunctionDefinitionNode node) { return node; } - public AstNode visit(BinaryOperatorNode node) { - if (true) { - System.out.println("Hej jeg kommer int i binarty2"); - } - AstNode left = node.getLeft(); - AstNode right = node.getRight(); + public AstNode visit(BinaryOperatorNode node) {// her bliver + og sådan evalueret. + + AstNode left = node.getLeft(); // Får venstre x som i result=x+y i node form + AstNode right = node.getRight();// Får højre y i node form + boolean valid_type_left = false; + boolean valid_type_right = false; + if (left instanceof IdentifierNode) { - left = getVariable((IdentifierNode) left); + left = getVariable((IdentifierNode) left); // Vis x giv mig x value } else if (left instanceof BinaryOperatorNode) { left = visit((BinaryOperatorNode) left); } if (right instanceof IdentifierNode) { - right = getVariable((IdentifierNode) right); + right = getVariable((IdentifierNode) right);// Vis y giv mig y value } else if (right instanceof BinaryOperatorNode) { right = visit((BinaryOperatorNode) right); } + // Lav type check her. - if (left instanceof IntNode && right instanceof IntNode) { + if (left instanceof IntNode && right instanceof IntNode) { // Her at udregning sker, som ikke burde ske. return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); } else if (left instanceof FloatNode && right instanceof FloatNode) { return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); diff --git a/test.carl b/test.carl index f5eaacb..23145d0 100644 --- a/test.carl +++ b/test.carl @@ -9,8 +9,10 @@ c = (d + d) + 5 print(c,"My Second C") c = (5 + d) * 5 c = 3 + (d + 5) - -var p : int = c + y +print("Her starter Carls test") +var poop : int =2 +var poop2 : int =2 +var p : int = poop+poop2 print(p, "CARLS PRINT" ) From ff15fd4b6c0ff0d6e4886adeabe3bfb88c83f202 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Thu, 25 Apr 2024 09:37:49 +0200 Subject: [PATCH 06/94] Bedre start Variable navne og type bliver nu gemt i value table istedet for :D --- .../carl/Semantic_A/Visitor.java | 66 +++++++++++++++---- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java index 0f59902..5cfbd00 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java @@ -86,7 +86,7 @@ public void visit(IfStatementNode node) { scopes.remove(localTable); } - public AstNode getVariable(IdentifierNode node) { + public Type getVariable(IdentifierNode node) { // for (HashMap vTable : scopes) { if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { // Tester om x er der, ev til bool return scopes.getFirst().get(node.getIdentifier().toString());// i scope, giv mig x node @@ -264,31 +264,73 @@ public AstNode visit(FunctionDefinitionNode node) { return node; } - public AstNode visit(BinaryOperatorNode node) {// her bliver + og sådan evalueret. - + public Type binaryoperator_type_check(BinaryOperatorNode node) { AstNode left = node.getLeft(); // Får venstre x som i result=x+y i node form AstNode right = node.getRight();// Får højre y i node form + boolean valid_type_left = false; boolean valid_type_right = false; - + + Type left_type = Type.VOID; + Type right_Type= Type.VOID; + if (left instanceof IdentifierNode) { - left = getVariable((IdentifierNode) left); // Vis x giv mig x value + left_type = getVariable((IdentifierNode) left); // Vis x giv mig x value } else if (left instanceof BinaryOperatorNode) { - left = visit((BinaryOperatorNode) left); + left_type = binaryoperator_type_check((BinaryOperatorNode) left); + } else if (left instanceof IntNode) { + left_type = Type.INT; + } else if (left instanceof FloatNode) { + left_type = Type.FLOAT; } + if (right instanceof IdentifierNode) { - right = getVariable((IdentifierNode) right);// Vis y giv mig y value + right_Type = getVariable((IdentifierNode) right);// Vis y giv mig y value //! Jeg vil gerne have det + // retunere type istedet for } else if (right instanceof BinaryOperatorNode) { - right = visit((BinaryOperatorNode) right); + right_Type = binaryoperator_type_check((BinaryOperatorNode) right); // ! Jeg vil gerne have det retunere // type istedet for } + else if (right instanceof IntNode) { + right_Type = Type.INT; + }else if (right instanceof FloatNode) { + right_Type = Type.FLOAT; + } + // Lav type check her. - if (left instanceof IntNode && right instanceof IntNode) { // Her at udregning sker, som ikke burde ske. - return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); + if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. + return Type.INT; + } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { + return Type.FLOAT; + } + System.out.println("Wrong types for binnary operation:"+left_type+":"+left+" And:"+right+":"+right_Type); + return Type.VOID; + } + + public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node){ + + AstNode left = node.getLeft(); + AstNode right = node.getRight(); + + if (left instanceof IdentifierNode) { + left = getVariable((IdentifierNode) left); + } else if (left instanceof RelationsAndLogicalOperatorNode) { + left = visit((RelationsAndLogicalOperatorNode) left); + } + if (right instanceof IdentifierNode) { + right = getVariable((IdentifierNode) right); + } else if (right instanceof RelationsAndLogicalOperatorNode) { + right = visit((RelationsAndLogicalOperatorNode) right); + } + if (left instanceof IntNode && right instanceof IntNode) { + return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); } else if (left instanceof FloatNode && right instanceof FloatNode) { - return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); + return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); + } else if (left instanceof BoolNode && right instanceof BoolNode) { + return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); } - throw new RuntimeException("BinaryOperator not implemented clause"); + throw new RuntimeException("RelationsAndLogicalOperator not implemented clause"); + return Type.VOID; } public AstNode visit(RelationsAndLogicalOperatorNode node) { From c1704e0b88aae64a059b759838923940cb049332 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Thu, 25 Apr 2024 11:27:08 +0200 Subject: [PATCH 07/94] Shit as post --- .../carl/Semantic_A/Visitor.java | 138 +++++++----------- 1 file changed, 54 insertions(+), 84 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java index 5cfbd00..8ab8232 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java @@ -268,33 +268,11 @@ public Type binaryoperator_type_check(BinaryOperatorNode node) { AstNode left = node.getLeft(); // Får venstre x som i result=x+y i node form AstNode right = node.getRight();// Får højre y i node form - boolean valid_type_left = false; - boolean valid_type_right = false; - Type left_type = Type.VOID; - Type right_Type= Type.VOID; - - if (left instanceof IdentifierNode) { - left_type = getVariable((IdentifierNode) left); // Vis x giv mig x value - } else if (left instanceof BinaryOperatorNode) { - left_type = binaryoperator_type_check((BinaryOperatorNode) left); - } else if (left instanceof IntNode) { - left_type = Type.INT; - } else if (left instanceof FloatNode) { - left_type = Type.FLOAT; - } + Type right_Type = Type.VOID; - if (right instanceof IdentifierNode) { - right_Type = getVariable((IdentifierNode) right);// Vis y giv mig y value //! Jeg vil gerne have det - // retunere type istedet for - } else if (right instanceof BinaryOperatorNode) { - right_Type = binaryoperator_type_check((BinaryOperatorNode) right); // ! Jeg vil gerne have det retunere // type istedet for - } - else if (right instanceof IntNode) { - right_Type = Type.INT; - }else if (right instanceof FloatNode) { - right_Type = Type.FLOAT; - } + left_type = getType(left); + right_Type = getType(right); // Lav type check her. @@ -303,83 +281,75 @@ else if (right instanceof IntNode) { } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { return Type.FLOAT; } - System.out.println("Wrong types for binnary operation:"+left_type+":"+left+" And:"+right+":"+right_Type); + System.out.println( + "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); return Type.VOID; } - public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node){ + public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { AstNode left = node.getLeft(); AstNode right = node.getRight(); - - if (left instanceof IdentifierNode) { - left = getVariable((IdentifierNode) left); - } else if (left instanceof RelationsAndLogicalOperatorNode) { - left = visit((RelationsAndLogicalOperatorNode) left); - } - if (right instanceof IdentifierNode) { - right = getVariable((IdentifierNode) right); - } else if (right instanceof RelationsAndLogicalOperatorNode) { - right = visit((RelationsAndLogicalOperatorNode) right); - } - if (left instanceof IntNode && right instanceof IntNode) { - return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); - } else if (left instanceof FloatNode && right instanceof FloatNode) { - return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); - } else if (left instanceof BoolNode && right instanceof BoolNode) { - return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); + + Type left_type = Type.VOID; + Type right_Type = Type.VOID; + + left_type = getType(left); + right_Type = getType(right); + + if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. + return Type.BOOLEAN; + } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { + return Type.BOOLEAN; + } else if (left_type == Type.BOOLEAN && right_Type == Type.BOOLEAN) { + return Type.BOOLEAN; } - throw new RuntimeException("RelationsAndLogicalOperator not implemented clause"); + + System.out.println( + "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); return Type.VOID; } - public AstNode visit(RelationsAndLogicalOperatorNode node) { - AstNode left = node.getLeft(); - AstNode right = node.getRight(); - if (left instanceof IdentifierNode) { - left = getVariable((IdentifierNode) left); - } else if (left instanceof RelationsAndLogicalOperatorNode) { - left = visit((RelationsAndLogicalOperatorNode) left); - } - if (right instanceof IdentifierNode) { - right = getVariable((IdentifierNode) right); - } else if (right instanceof RelationsAndLogicalOperatorNode) { - right = visit((RelationsAndLogicalOperatorNode) right); - } - if (left instanceof IntNode && right instanceof IntNode) { - return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); - } else if (left instanceof FloatNode && right instanceof FloatNode) { - return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); - } else if (left instanceof BoolNode && right instanceof BoolNode) { - return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); + public Type getType(AstNode node) { + Type type = Type.VOID; + if (node instanceof IdentifierNode) { + type = getVariable((IdentifierNode) node); // Vis x giv mig x value + } else if (node instanceof BinaryOperatorNode) { + type = binaryoperator_type_check((BinaryOperatorNode) node); + } else if (node instanceof IntNode) { + type = Type.INT; + } else if (node instanceof FloatNode) { + type = Type.FLOAT; + } else if (node instanceof BoolNode) { + type = Type.BOOLEAN; } - throw new RuntimeException("RelationsAndLogicalOperator not implemented clause"); + + return type; + } - public AstNode visit(WhileLoopNode node) { + public void visit(WhileLoopNode node) { // ! Type cheking her er at checke expression while(expresion) sikre at det + // er en bool type AstNode toCheck = (node.getExpression()).getNode(); + Type tocheck_type = Type.VOID; + if (toCheck instanceof IdentifierNode) { - toCheck = getVariable((IdentifierNode) node.getExpression().getNode()); + tocheck_type = getVariable((IdentifierNode) node.getExpression().getNode()); // skal evaluere til bool } else if (toCheck instanceof RelationsAndLogicalOperatorNode) { - toCheck = visit((RelationsAndLogicalOperatorNode) toCheck); + tocheck_type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) toCheck); // skal også til bool + } + if (toCheck instanceof BoolNode) { + tocheck_type = Type.BOOLEAN; } - while ((toCheck instanceof BoolNode)) { - if (((BoolNode) toCheck).getValue()) { - HashMap localTable = new HashMap<>(); - scopes.add(localTable); - visit(node.getBlock()); - toCheck = visit(node.getExpression().getNode()); - if (toCheck instanceof IdentifierNode) { - toCheck = getVariable((IdentifierNode) node.getExpression().getNode()); - } else if (toCheck instanceof RelationsAndLogicalOperatorNode) { - toCheck = visit((RelationsAndLogicalOperatorNode) toCheck); - } - scopes.remove(localTable); - } else { - return node; - } + if (tocheck_type != Type.BOOLEAN) { + System.out.println("While loop condition wrong type should be bool, but was:"+tocheck_type + "and got thi node"+toCheck); } - throw new RuntimeException("Did not get into while statement"); + HashMap localTable = new HashMap<>(); + scopes.add(localTable); + visit(node.getBlock()); + toCheck = visit(node.getExpression().getNode()); + scopes.remove(localTable); + } } From 9ef2138f4b2b7ff11ad893e86d567d6d9cf20e69 Mon Sep 17 00:00:00 2001 From: DeeKahy <97156953+DeeKahy@users.noreply.github.com> Date: Thu, 25 Apr 2024 12:26:01 +0200 Subject: [PATCH 08/94] test --- .classpath | 63 +++ .factorypath | 11 + .project | 34 ++ .settings/org.eclipse.core.resources.prefs | 5 + .settings/org.eclipse.jdt.apt.core.prefs | 4 + .settings/org.eclipse.jdt.core.prefs | 9 + .settings/org.eclipse.m2e.core.prefs | 4 + .../carl/SimpleFunctionIntegrationTest.java | 456 ++++++++++++++++++ 8 files changed, 586 insertions(+) create mode 100644 .classpath create mode 100644 .factorypath create mode 100644 .project create mode 100644 .settings/org.eclipse.core.resources.prefs create mode 100644 .settings/org.eclipse.jdt.apt.core.prefs create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..13b732d --- /dev/null +++ b/.classpath @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.factorypath b/.factorypath new file mode 100644 index 0000000..a560e81 --- /dev/null +++ b/.factorypath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..9b75c4a --- /dev/null +++ b/.project @@ -0,0 +1,34 @@ + + + carl + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + + + 1713987443606 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..c46ad2d --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/test/java=UTF-8 +encoding//target/generated-sources/antlr4=UTF-8 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 0000000..dfa4f3a --- /dev/null +++ b/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=true +org.eclipse.jdt.apt.genSrcDir=target/generated-sources/annotations +org.eclipse.jdt.apt.genTestSrcDir=target/generated-test-sources/test-annotations diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..29f57ea --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.processAnnotations=enabled +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java new file mode 100644 index 0000000..ce2df7e --- /dev/null +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java @@ -0,0 +1,456 @@ +package dk.aau.cs_24_sw_4_16.carl; + +import dk.aau.cs_24_sw_4_16.carl.CstToAst.AstNode; +import dk.aau.cs_24_sw_4_16.carl.CstToAst.CstToAstVisitor; +import dk.aau.cs_24_sw_4_16.carl.Interpreter.Interpreter; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTree; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import static org.junit.jupiter.api.Assertions.*; + +public class SimpleFunctionIntegrationTest { + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final PrintStream originalOut = System.out; + + @BeforeEach + public void setUpStreams() { + System.setOut(new PrintStream(outContent)); + } + + @AfterEach + public void restoreStreams() { + System.setOut(originalOut); + } + + @Test + public void testingPrintSatement() throws Exception { + String code = """ + print("test") + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + assertEquals("\"test\"".trim(), outContent.toString().trim(), "expected the output to be test"); + } + + @Test + public void testingVariable() throws Exception { + String code = """ + var x : int = 42 + var y : int = x + print(y) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("42".trim(), outContent.toString().trim()); + } + + @Test + public void testingIncrementOperator() throws Exception { + String code = """ + var l : int = 1 + l = l + 1 + print(l) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + assertEquals("2".trim(), outContent.toString().trim(), + "Expected the output to be 2 because 'l' was incremented once."); + } + + @Test + public void testingAddition() throws Exception { + String code = """ + var x : int = (1 + 2) - 2 + print(x) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("1".trim(), outContent.toString().trim()); + } + + @Test + public void testingIfStatement() throws Exception { + String code = """ + var x : int = 10 + var y : int = 0 + if x > 5 { + y = 1 + } else { + y = 2 + } + print(y) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("1".trim(), outContent.toString().trim(), + "Expected the output to be 1 because x > 5 and therefore, y should be set to 1."); + } + + @Test + public void testingIfElseChain() throws Exception { + String code = """ + var x : int = 1 + var y : int = 0 + if x > 5 { + y = 1 + } else if x < -5 { + y = 2 + } else { + y = 3 + } + print(y) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("3".trim(), outContent.toString().trim(), + "Expected the output to be 3 because x does not meet the other conditions and therefore, y should be set to 3."); + } + + @Test + public void testingMult() throws Exception { + String code = """ + var x : int = (1 * 4) / 2 + print(x) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("2".trim(), outContent.toString().trim()); + } + + @Test + public void testingWhile() throws Exception { + String code = """ + var d : int = 0 + while d <= 5{ + d = d + 1 + } + print(d) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("6".trim(), outContent.toString().trim()); + } + + @Test + public void testingFunction() throws Exception { + String code = """ + fn calculate() -> int { + return 42 + } + var result: int = calculate() + print(result) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("42".trim(), outContent.toString().trim(), "Expected the output to be 42"); + } + + @Test + public void testingSubtraction() throws Exception { + String code = """ + var x : int = 10 - 5 + print(x) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("5".trim(), outContent.toString().trim(), "Expected the output to be 5 because 10 - 5 equals 5."); + } + + @Test + public void testingDivision() throws Exception { + String code = """ + var x : int = 10 / 2 + print(x) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("5".trim(), outContent.toString().trim(), "Expected the output to be 5 because 10 / 2 equals 5."); + } + + @Test + public void testingModulus() throws Exception { + String code = """ + var x : int = 10 % 3 + print(x) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("1".trim(), outContent.toString().trim(), "Expected the output to be 1 because 10 % 3 equals 1."); + } + + @Test + public void testingInt() throws Exception { + String code = """ + var x : int = 42 + print(x) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + assertEquals("42".trim(), outContent.toString().trim()); + } + + @Test + public void testingFloat() throws Exception { + String code = """ + var x : float = 42.5 + print(x) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + assertEquals("42.5".trim(), outContent.toString().trim()); + } + + @Test + public void testingString() throws Exception { + String code = """ + var x : string = "test" + print(x) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + assertEquals("\"test\"".trim(), outContent.toString().trim()); + } + + @Test + public void testingBool() throws Exception { + String code = """ + var x : bool = true + print(x) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + assertEquals("true".trim(), outContent.toString().trim()); + } + // @Test + // public void testingRelationalOperators() throws Exception { + // String code = """ + // var f : int = 3 + // var g : int = 4 + // var h : bool = f < g + // print(h) + // """; + // + // InputStream stream = new + // ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + // CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + // CommonTokenStream tokens = new CommonTokenStream(lexer); + // CARLParser parser = new CARLParser(tokens); + // ParseTree tree = parser.program(); + // CstToAstVisitor visitor = new CstToAstVisitor(); + // AstNode astRoot = visitor.visit(tree); + // + // Interpreter interpreter = new Interpreter(); + // interpreter.visit(astRoot); + // + // assertEquals("true", outContent.toString().trim(), "Expected the output to be + // true because 3 < 4."); + // } + + @Test + public void testingStruct1() throws Exception { + String code = """ + var Goblin : enemy ={ + var difficulty : int = 1 + var health : int = 5300 + var symbol : string= "O" + } + var test : int = 5 + test = enemy.Goblin.health + print(test) + + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + assertEquals("5300".trim(), outContent.toString().trim()); + } + +} From b1e0c48e45477bbbfedc96ed897c41b39bdb239d Mon Sep 17 00:00:00 2001 From: DeeKahy <97156953+DeeKahy@users.noreply.github.com> Date: Thu, 25 Apr 2024 12:29:28 +0200 Subject: [PATCH 09/94] test --- .../carl/SimpleFunctionIntegrationTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java index ce2df7e..d610c1b 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java @@ -453,4 +453,33 @@ public void testingStruct1() throws Exception { assertEquals("5300".trim(), outContent.toString().trim()); } + @Test + public void testingStruct2() throws Exception { + String code = """ + var Goblin : enemy ={ + var difficulty : int = 1 + var health : int = 5300 + var symbol : string= "O" + var gender : string= "orcacnian" + } + var test : int = 5 + test = enemy.Goblin.gender + print(test) + + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + assertEquals("orcacnian".trim(), outContent.toString().trim()); + } + } From 8bafd495f0fea46c572756e8d2655e7d9b8b5039 Mon Sep 17 00:00:00 2001 From: DeeKahy <97156953+DeeKahy@users.noreply.github.com> Date: Thu, 25 Apr 2024 12:52:29 +0200 Subject: [PATCH 10/94] made some tests for structs --- .../carl/SimpleFunctionIntegrationTest.java | 90 ++++++++++++++++++- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java index d610c1b..d7a6eca 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java @@ -462,7 +462,7 @@ public void testingStruct2() throws Exception { var symbol : string= "O" var gender : string= "orcacnian" } - var test : int = 5 + var test : string = "ssssssss" test = enemy.Goblin.gender print(test) @@ -479,7 +479,93 @@ public void testingStruct2() throws Exception { Interpreter interpreter = new Interpreter(); interpreter.visit(astRoot); - assertEquals("orcacnian".trim(), outContent.toString().trim()); + assertEquals("\"orcacnian\"".trim(), outContent.toString().trim()); } + @Test + public void testingStruct3() throws Exception { + String code = """ + var Goblin : enemy ={ + var difficulty : int = 1 + var health : int = 5300 + var symbol : string= "O" + var gender : string= "orcacnian" + } + var test : string = "ssssssss" + test = enemy.Goblin.gender + print(test) + + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + assertEquals("\"orcacnian\"".trim(), outContent.toString().trim()); + } + + @Test + public void testingStruct4() throws Exception { + String code = """ + var Goblin : enemy ={ + var difficulty : int = 1 + var health : int = 5300 + var symbol : string= "O" + var gender : string= "orcacnian" + } + var test : string = "ssssssss" + test = enemy.get(0).gender + print(test) + + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + assertEquals("\"orcacnian\"".trim(), outContent.toString().trim()); + } + + @Test + public void testingStruct5() throws Exception { + String code = """ + var Goblin : enemy ={ + var difficulty : int = 1 + var health : int = 5300 + var symbol : string= "O" + var gender : string= "orcacnian" + } + var test : int =44 + test = enemy.size() + print(test) + + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + assertEquals("1".trim(), outContent.toString().trim()); + } } From d820d2f62e1625892d4aa782cfaeb13bd5629443 Mon Sep 17 00:00:00 2001 From: DeeKahy <97156953+DeeKahy@users.noreply.github.com> Date: Thu, 25 Apr 2024 12:56:39 +0200 Subject: [PATCH 11/94] Update .gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 92322c4..7fc49cb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ .idea/ target/ +.settings/ +.classpath +.project +.factorypath From 2bb1e46cdd5e9db93ed1d6759114eae1e2c733b1 Mon Sep 17 00:00:00 2001 From: DeeKahy <97156953+DeeKahy@users.noreply.github.com> Date: Thu, 25 Apr 2024 12:58:50 +0200 Subject: [PATCH 12/94] whops didnt want to add my nvim config for java --- .classpath | 63 ---------------------- .factorypath | 11 ---- .project | 34 ------------ .settings/org.eclipse.core.resources.prefs | 5 -- .settings/org.eclipse.jdt.apt.core.prefs | 4 -- .settings/org.eclipse.jdt.core.prefs | 9 ---- .settings/org.eclipse.m2e.core.prefs | 4 -- 7 files changed, 130 deletions(-) delete mode 100644 .classpath delete mode 100644 .factorypath delete mode 100644 .project delete mode 100644 .settings/org.eclipse.core.resources.prefs delete mode 100644 .settings/org.eclipse.jdt.apt.core.prefs delete mode 100644 .settings/org.eclipse.jdt.core.prefs delete mode 100644 .settings/org.eclipse.m2e.core.prefs diff --git a/.classpath b/.classpath deleted file mode 100644 index 13b732d..0000000 --- a/.classpath +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.factorypath b/.factorypath deleted file mode 100644 index a560e81..0000000 --- a/.factorypath +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/.project b/.project deleted file mode 100644 index 9b75c4a..0000000 --- a/.project +++ /dev/null @@ -1,34 +0,0 @@ - - - carl - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - - - 1713987443606 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - - diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index c46ad2d..0000000 --- a/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,5 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/test/java=UTF-8 -encoding//target/generated-sources/antlr4=UTF-8 -encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs deleted file mode 100644 index dfa4f3a..0000000 --- a/.settings/org.eclipse.jdt.apt.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.apt.aptEnabled=true -org.eclipse.jdt.apt.genSrcDir=target/generated-sources/annotations -org.eclipse.jdt.apt.genTestSrcDir=target/generated-test-sources/test-annotations diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 29f57ea..0000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 -org.eclipse.jdt.core.compiler.compliance=21 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.processAnnotations=enabled -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=21 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 From 3dd793bbb1e3e2fef23e3254881d200a3f1cf4f2 Mon Sep 17 00:00:00 2001 From: mantarias Date: Thu, 25 Apr 2024 15:43:11 +0200 Subject: [PATCH 13/94] code to handle binary operations with method call and property access --- .../cs_24_sw_4_16/carl/Interpreter/Interpreter.java | 8 ++++++++ test.carl | 13 +++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java index 3107891..5052bc1 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java @@ -455,11 +455,19 @@ public AstNode visit(BinaryOperatorNode node) { left = getVariable((IdentifierNode) left); } else if (left instanceof BinaryOperatorNode) { left = visit((BinaryOperatorNode) left); + } else if (left instanceof MethodCallNode) { + left = visit((MethodCallNode) left); + } else if (left instanceof PropertyAccessNode) { + left = visit((PropertyAccessNode) left); } if (right instanceof IdentifierNode) { right = getVariable((IdentifierNode) right); } else if (right instanceof BinaryOperatorNode) { right = visit((BinaryOperatorNode) right); + } else if (right instanceof MethodCallNode) { + right = visit((MethodCallNode) right); + } else if (right instanceof PropertyAccessNode) { + right = visit((PropertyAccessNode) right); } if (left instanceof IntNode && right instanceof IntNode) { diff --git a/test.carl b/test.carl index 7d49b61..6a294ab 100644 --- a/test.carl +++ b/test.carl @@ -60,6 +60,15 @@ var Goblin : enemy ={ var health : int = 500 var symbol : string= "O" } -var test : int = 5 -test = enemy.get(1).health +var Goblin2 : enemy ={ + var difficulty : int = 1 + var health : int = 500 + var symbol : string= "O" +} +var Goblin3 : enemy ={ + var difficulty : int = 1 + var health : int = 500 + var symbol : string= "O" +} +var test : int = 1..enemy.size() print(test) \ No newline at end of file From a831ded90f76e68ee21c9f9051d7ad6285619add Mon Sep 17 00:00:00 2001 From: MShadiF Date: Fri, 26 Apr 2024 09:42:03 +0200 Subject: [PATCH 14/94] lille update --- .../carl/Semantic_A/Visitor.java | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java index 8ab8232..7f9a6af 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java @@ -6,8 +6,8 @@ public class Visitor { HashMap fTable; // function table, identifier(x) og node - HashMap vTable;// variable table, identifier(x) og node(int) - Stack> scopes; // scope table, variable identifier(x) og node + HashMap ETable;// variable table, identifier(x) og node(int) + Stack> scopes; // scope table, variable identifier(x) og node Deque activeScope;// Hvilket scope vi er i nu boolean printyes = true;// ! SLET SENERE @@ -18,11 +18,11 @@ public AstNode visit(AstNode node) { System.out.println("Hej jeg kommer int i visitor"); } fTable = new HashMap<>(); - vTable = new HashMap<>(); + ETable = new HashMap<>(); scopes = new Stack<>(); activeScope = new ArrayDeque<>(); activeScope.push(0); - scopes.add(vTable); + scopes.add(ETable); return visit((ProgramNode) node); } else if (node instanceof StatementNode) { @@ -33,7 +33,7 @@ public AstNode visit(AstNode node) { return node; } - public AstNode visit(StatementNode node) { + public void visit(StatementNode node) { if (node.getNode() instanceof AssignmentNode) { visit((AssignmentNode) node.getNode()); } else if (node.getNode() instanceof VariableDeclarationNode) { @@ -54,7 +54,7 @@ public AstNode visit(StatementNode node) { } else if (node.getNode() instanceof ReturnStatementNode) { return visit((ReturnStatementNode) node.getNode()); } - return null; + } public AstNode visit(ReturnStatementNode node) { @@ -62,7 +62,7 @@ public AstNode visit(ReturnStatementNode node) { } public void visit(IfStatementNode node) { - HashMap localTable = new HashMap<>(); // ny lokalt value table + HashMap localTable = new HashMap<>(); // ny lokalt value table scopes.add(localTable); // Tilføjer det til stacken med scopes boolean visited = false; for (int i = 0; i < node.getExpressions().size(); i++) { // Hver expression er en if statement. Ligesom hver @@ -102,7 +102,7 @@ public Type getVariable(IdentifierNode node) { public void visit(AssignmentNode node) { - for (HashMap vTable : scopes) { + for (HashMap vTable : scopes) { if (vTable.containsKey(node.getIdentifier().toString())) { // tjek if variable x is scopes bool AstNode nodeToChange = vTable.get(node.getIdentifier().toString());// retunere node AstNode toChange = node.getValue(); // Højre side af assignmen x= tochange vil retunere node @@ -193,7 +193,7 @@ public AstNode visit(ProgramNode node) { return node; } - public AstNode visit(FunctionCallNode node) { + public void visit(FunctionCallNode node) { if (node.getFunctionName().toString().equals("print")) { InbuildClasses.print(node, scopes, activeScope); } else { @@ -232,7 +232,7 @@ public AstNode visit(FunctionCallNode node) { return node; } - public AstNode visit(BlockNode node) { + public void visit(BlockNode node) { for (AstNode statement : node.getStatements()) { if (((StatementNode) statement).getNode() instanceof ReturnStatementNode) { @@ -241,10 +241,9 @@ public AstNode visit(BlockNode node) { visit((StatementNode) statement); } } - return node; } - public AstNode visit(ExpressionNode node) { + public void visit(ExpressionNode node) { if (node.getNode() instanceof FunctionCallNode) { return visit((FunctionCallNode) node.getNode()); } else if (node.getNode() instanceof RelationsAndLogicalOperatorNode) { @@ -255,13 +254,12 @@ public AstNode visit(ExpressionNode node) { return node; } - public AstNode visit(FunctionDefinitionNode node) { + public void visit(FunctionDefinitionNode node) { if (!fTable.containsKey(node.getIdentifier().toString())) { fTable.put(node.getIdentifier().toString(), node); } else { throw new RuntimeException("function " + node.getIdentifier() + " already exists"); } - return node; } public Type binaryoperator_type_check(BinaryOperatorNode node) { @@ -312,6 +310,7 @@ public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { public Type getType(AstNode node) { Type type = Type.VOID; + if (node instanceof IdentifierNode) { type = getVariable((IdentifierNode) node); // Vis x giv mig x value } else if (node instanceof BinaryOperatorNode) { @@ -322,10 +321,14 @@ public Type getType(AstNode node) { type = Type.FLOAT; } else if (node instanceof BoolNode) { type = Type.BOOLEAN; + } else if (node instanceof ExpressionNode){ + if(((ExpressionNode) node).getNode() instanceof BinaryOperatorNode){ + type = binaryoperator_type_check((BinaryOperatorNode) node); + } else if (((ExpressionNode) node).getNode() instanceof RelationsAndLogicalOperatorNode){ + type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) node); + } } - return type; - } public void visit(WhileLoopNode node) { // ! Type cheking her er at checke expression while(expresion) sikre at det From cca6d1741e1baa82951a92963f84ecc9926e7e78 Mon Sep 17 00:00:00 2001 From: Vincent Kosteyev Bechmann Date: Fri, 26 Apr 2024 10:27:22 +0200 Subject: [PATCH 15/94] We DO NOT want IDE folders in our project BEGONE VSCODE CONFIG --- .gitignore | 1 + .vscode/settings.json | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 92322c4..3d5af4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea/ +.vscode/ target/ diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index c995aa5..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "java.debug.settings.onBuildFailureProceed": true -} \ No newline at end of file From 3e26e69907a51e67dbb4d831dcb64f2283b71d26 Mon Sep 17 00:00:00 2001 From: MShadiF Date: Fri, 26 Apr 2024 15:34:18 +0200 Subject: [PATCH 16/94] I gang med type checker --- .../carl/Semantic_A/SemanticAnalyzer.java | 10 +- .../carl/Semantic_A/TypeChecker.java | 102 +++ .../carl/Semantic_A/Visitor.java | 699 +++++++++--------- 3 files changed, 457 insertions(+), 354 deletions(-) create mode 100644 src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java index b723928..9bc7f52 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java @@ -7,11 +7,13 @@ public class SemanticAnalyzer { public void analyze(AstNode root) throws SemanticException { if (printTest) { - System.out.println("Hej jeg kommer her ind"); + // System.out.println("Hej jeg kommer her ind"); } - System.out.println("Her starter visitor class"); - Visitor visitor = new Visitor(); - visitor.visit(root); + // System.out.println("Her starter visitor class"); + + TypeChecker typeChecker = new TypeChecker(); + typeChecker.visitor(root); + System.out.println("Her stopper visitor class"); if (root != null) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java new file mode 100644 index 0000000..2dbb981 --- /dev/null +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -0,0 +1,102 @@ +package dk.aau.cs_24_sw_4_16.carl.Semantic_A; + +import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashMap; +import java.util.Stack; + +public class TypeChecker { + HashMap fTable; // function table, identifier(x) og node + HashMap ETable;// variable table, identifier(x) og node(int) + Stack> scopes; // scope table, variable identifier(x) og node + Deque activeScope;// Hvilket scope vi er i nu + + public TypeChecker() { + fTable = new HashMap<>(); + ETable = new HashMap<>(); + scopes = new Stack<>(); + activeScope = new ArrayDeque<>(); + activeScope.push(0); + scopes.add(ETable); + } + + public void visitor(AstNode node) { + if (node instanceof ProgramNode) { + visitProgramNode((ProgramNode) node); + } + } + + public void visitProgramNode(ProgramNode node) { + for (AstNode statement : node.getStatements()) { + visitStatements((StatementNode) statement); + } + } + + public void visitStatements(StatementNode node) { + if (node.getNode() instanceof VariableDeclarationNode) { + visitVariableDeclaration((VariableDeclarationNode) node.getNode()); + } + } + + + private void visitVariableDeclaration(VariableDeclarationNode node) { + boolean found = scopes.getFirst().containsKey(node.getIdentifier().toString()); + + for (int i = activeScope.getLast(); i < scopes.size(); i++) { + if (scopes.get(i).containsKey(node.getIdentifier().toString())) { + found = true; + } + } + if (!found) { + System.out.println("We in! " + node.getType()); + Type toChange = getType(node); + + if (node.getValue() instanceof BinaryOperatorNode) { + // toChange = visit((BinaryOperatorNode) node.getValue()); + + // scopes.getLast().put(node.getIdentifier().toString(), toChange); + } else if (node.getValue() instanceof IdentifierNode) { + for (HashMap ETable : scopes) { + if (ETable.containsKey(toChange.toString())) { + scopes.getLast().put(node.getIdentifier().toString(), ETable.get(toChange.toString())); + } + } + } else { + scopes.getLast().put(node.getIdentifier().toString(), toChange); + } + + } else { + throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); + } + } + + + public Type getType(AstNode node) { + Type type = Type.VOID; + + if (node instanceof IdentifierNode) { +// type = getVariable((IdentifierNode) node); // Vis x giv mig x value + } else if (node instanceof BinaryOperatorNode) { +// type = binaryoperator_type_check((BinaryOperatorNode) node); + } else if (node instanceof IntNode) { + type = Type.INT; + System.out.println(((IntNode) node).getValue() + " We in intNode"); + } else if (node instanceof FloatNode) { + type = Type.FLOAT; + } else if (node instanceof BoolNode) { + type = Type.BOOLEAN; + } else if (node instanceof ExpressionNode){ +// if(((ExpressionNode) node).getNode() instanceof BinaryOperatorNode){ +// type = binaryoperator_type_check((BinaryOperatorNode) node); +// } else if (((ExpressionNode) node).getNode() instanceof RelationsAndLogicalOperatorNode){ +// type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) node); +// } + } else if (false) { + + } + return type; + } + +} diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java index 7f9a6af..bfb5bce 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java @@ -5,354 +5,353 @@ import dk.aau.cs_24_sw_4_16.carl.Interpreter.InbuildClasses;; public class Visitor { - HashMap fTable; // function table, identifier(x) og node - HashMap ETable;// variable table, identifier(x) og node(int) - Stack> scopes; // scope table, variable identifier(x) og node - Deque activeScope;// Hvilket scope vi er i nu - - boolean printyes = true;// ! SLET SENERE - - public AstNode visit(AstNode node) { - if (node instanceof ProgramNode) { - if (printyes) { - System.out.println("Hej jeg kommer int i visitor"); - } - fTable = new HashMap<>(); - ETable = new HashMap<>(); - scopes = new Stack<>(); - activeScope = new ArrayDeque<>(); - activeScope.push(0); - scopes.add(ETable); - - return visit((ProgramNode) node); - } else if (node instanceof StatementNode) { - return visit((StatementNode) node); - } else if (node instanceof ExpressionNode) { - return visit((ExpressionNode) node); - } - return node; - } - - public void visit(StatementNode node) { - if (node.getNode() instanceof AssignmentNode) { - visit((AssignmentNode) node.getNode()); - } else if (node.getNode() instanceof VariableDeclarationNode) { - visit((VariableDeclarationNode) node.getNode()); - } else if (node.getNode() instanceof FunctionCallNode) { - return visit((FunctionCallNode) node.getNode()); - } else if (node.getNode() instanceof FunctionDefinitionNode) { - return visit((FunctionDefinitionNode) node.getNode()); - } else if (node.getNode() instanceof WhileLoopNode) { - return visit((WhileLoopNode) node.getNode()); - } else if (node.getNode() instanceof IfStatementNode) { - visit((IfStatementNode) node.getNode()); - } else if (node.getNode() instanceof BinaryOperatorNode) { - visit((BinaryOperatorNode) node.getNode()); - if (true) { - System.out.println("Hej jeg kommer int i interpriter binaryoperator"); - } - } else if (node.getNode() instanceof ReturnStatementNode) { - return visit((ReturnStatementNode) node.getNode()); - } - - } - - public AstNode visit(ReturnStatementNode node) { - return node; - } - - public void visit(IfStatementNode node) { - HashMap localTable = new HashMap<>(); // ny lokalt value table - scopes.add(localTable); // Tilføjer det til stacken med scopes - boolean visited = false; - for (int i = 0; i < node.getExpressions().size(); i++) { // Hver expression er en if statement. Ligesom hver - // block er til den if statement - AstNode toCheck = node.getExpressions().get(i).getNode(); - if (node.getExpressions().get(i).getNode() instanceof IdentifierNode) { - toCheck = getVariable((IdentifierNode) node.getExpressions().get(i).getNode());// Hvis det er x så giv - // mig xnode - } else if (node.getExpressions().get(i).getNode() instanceof RelationsAndLogicalOperatorNode) { - toCheck = visit((RelationsAndLogicalOperatorNode) node.getExpressions().get(i).getNode()); - } - if (toCheck instanceof BoolNode && ((BoolNode) toCheck).getValue()) { - visit(node.getBlocks().get(i)); - visited = true; - break; - } - } - if (!visited && node.getExpressions().size() < node.getBlocks().size()) { - visit(node.getBlocks().get(node.getBlocks().size() - 1)); - } - scopes.remove(localTable); - } - - public Type getVariable(IdentifierNode node) { - // for (HashMap vTable : scopes) { - if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { // Tester om x er der, ev til bool - return scopes.getFirst().get(node.getIdentifier().toString());// i scope, giv mig x node - } - - for (int i = activeScope.getLast(); i < scopes.size(); i++) {// for at gå igennem hvert scope og tjekke for x - if (scopes.get(i).containsKey(node.getIdentifier().toString())) { - return scopes.get(i).get(node.getIdentifier().toString());// i i scope, giv mig x node - } - } - throw new RuntimeException("could not find the variable " + node.getIdentifier()); - } - - public void visit(AssignmentNode node) { - - for (HashMap vTable : scopes) { - if (vTable.containsKey(node.getIdentifier().toString())) { // tjek if variable x is scopes bool - AstNode nodeToChange = vTable.get(node.getIdentifier().toString());// retunere node - AstNode toChange = node.getValue(); // Højre side af assignmen x= tochange vil retunere node - if (toChange instanceof BinaryOperatorNode) { - toChange = visit((BinaryOperatorNode) toChange); // if x= 20+20 - } - if (toChange instanceof FunctionCallNode) { - toChange = visit((FunctionCallNode) toChange); // if x= functioncall(10) - } - if (toChange instanceof IdentifierNode) { - toChange = getVariable((IdentifierNode) toChange); // if x = y - } - if (node.getValue() instanceof RelationsAndLogicalOperatorNode) { // if x= 10<5 - toChange = visit((RelationsAndLogicalOperatorNode) toChange); - } - AstNode finalToChange = toChange; - switch (nodeToChange) { - case IntNode intNode when finalToChange instanceof IntNode -> - intNode.setValue(((IntNode) finalToChange).getValue()); - case FloatNode floatNode when finalToChange instanceof FloatNode -> - floatNode.setValue(((FloatNode) finalToChange).getValue()); - case StringNode stringNode when finalToChange instanceof StringNode -> - stringNode.setValue(((StringNode) finalToChange).getValue()); - case BoolNode boolNode when finalToChange instanceof BoolNode -> - boolNode.setValue(((BoolNode) finalToChange).getValue()); - case null, default -> throw new RuntimeException("Type mismatch"); - } - return; - } - } - - throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); - } - - public void visit(VariableDeclarationNode node) { - boolean found = false; - if (scopes.getFirst().containsKey(node.getIdentifier().toString())) {// finder x i scope FY FY - found = true; - } - - for (int i = activeScope.getLast(); i < scopes.size(); i++) {// finder x i et scope FY FY - if (scopes.get(i).containsKey(node.getIdentifier().toString())) { - found = true; - } - } - if (!found) { // kunne ikke finde x i scope så kan gemme den - - AstNode toChange = node.getValue(); // x=value value = node eller 5 - if (node.getValue() instanceof BinaryOperatorNode) { // hvis x=2+2 - toChange = visit((BinaryOperatorNode) node.getValue()); // Henter type node efter operation node - scopes.getLast().put(node.getIdentifier().toString(), toChange); // Her sætter vi x til type node i - // scope hash map - } else if (toChange instanceof IdentifierNode) { // Vis x=y - for (HashMap vTable : scopes) {// For hvert scope skal vi prøve at finde variable - if (vTable.containsKey(toChange.toString())) {// Vis vi finder den i et scope - scopes.getLast().put(node.getIdentifier().toString(), vTable.get(toChange.toString())); - } - } - } else { - scopes.getLast().put(node.getIdentifier().toString(), toChange); // case hvor x=4 - } - - } else { // Fy fy den findes allerede - throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); - } - } - - public AstNode visit(TypeNode node) { - return node; - } - - public AstNode visit(BoolNode node) { - return node; - } - - public AstNode visit(IntNode node) { - return node; - } - - public AstNode visit(FloatNode node) { - return node; - } - - public AstNode visit(ProgramNode node) { - for (AstNode statement : node.getStatements()) { - visit(statement); - } - return node; - } - - public void visit(FunctionCallNode node) { - if (node.getFunctionName().toString().equals("print")) { - InbuildClasses.print(node, scopes, activeScope); - } else { - HashMap localTable = new HashMap<>(); - scopes.add(localTable); - activeScope.add(scopes.size() - 1); - - if (fTable.containsKey(node.getFunctionName().toString())) { - FunctionDefinitionNode function = fTable.get(node.getFunctionName().toString()); - List arguments = function.getArguments().getParameters(); - for (int i = 0; i < function.getArguments().getParameters().size(); i++) { - visit(new VariableDeclarationNode(arguments.get(i).getIdentifier(), arguments.get(i).getType(), - node.getArgument(i))); - } - AstNode test = visit(function.getBlock()); - - if (test instanceof ReturnStatementNode) { - AstNode returnValue = ((ReturnStatementNode) test).getReturnValue(); - if (returnValue instanceof IdentifierNode) { - returnValue = getVariable((IdentifierNode) returnValue); - } - scopes.remove(localTable); - activeScope.removeLast(); - if (function.getReturnType().getType().equals("void")) { - if (returnValue != null) { - throw new RuntimeException( - "cannot return a value in void function call or have code after return statement"); - } - return node; - } - - return returnValue; - } - } - } - return node; - } - - public void visit(BlockNode node) { - for (AstNode statement : node.getStatements()) { - - if (((StatementNode) statement).getNode() instanceof ReturnStatementNode) { - return visit((StatementNode) statement); - } else { - visit((StatementNode) statement); - } - } - } - - public void visit(ExpressionNode node) { - if (node.getNode() instanceof FunctionCallNode) { - return visit((FunctionCallNode) node.getNode()); - } else if (node.getNode() instanceof RelationsAndLogicalOperatorNode) { - return visit((RelationsAndLogicalOperatorNode) node.getNode()); - } else if (node.getNode() instanceof BinaryOperatorNode) { - return visit((BinaryOperatorNode) node.getNode()); - } - return node; - } - - public void visit(FunctionDefinitionNode node) { - if (!fTable.containsKey(node.getIdentifier().toString())) { - fTable.put(node.getIdentifier().toString(), node); - } else { - throw new RuntimeException("function " + node.getIdentifier() + " already exists"); - } - } - - public Type binaryoperator_type_check(BinaryOperatorNode node) { - AstNode left = node.getLeft(); // Får venstre x som i result=x+y i node form - AstNode right = node.getRight();// Får højre y i node form - - Type left_type = Type.VOID; - Type right_Type = Type.VOID; - - left_type = getType(left); - right_Type = getType(right); - - // Lav type check her. - - if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. - return Type.INT; - } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { - return Type.FLOAT; - } - System.out.println( - "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); - return Type.VOID; - } - - public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { - - AstNode left = node.getLeft(); - AstNode right = node.getRight(); - - Type left_type = Type.VOID; - Type right_Type = Type.VOID; - - left_type = getType(left); - right_Type = getType(right); - - if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. - return Type.BOOLEAN; - } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { - return Type.BOOLEAN; - } else if (left_type == Type.BOOLEAN && right_Type == Type.BOOLEAN) { - return Type.BOOLEAN; - } - - System.out.println( - "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); - return Type.VOID; - } - - public Type getType(AstNode node) { - Type type = Type.VOID; - - if (node instanceof IdentifierNode) { - type = getVariable((IdentifierNode) node); // Vis x giv mig x value - } else if (node instanceof BinaryOperatorNode) { - type = binaryoperator_type_check((BinaryOperatorNode) node); - } else if (node instanceof IntNode) { - type = Type.INT; - } else if (node instanceof FloatNode) { - type = Type.FLOAT; - } else if (node instanceof BoolNode) { - type = Type.BOOLEAN; - } else if (node instanceof ExpressionNode){ - if(((ExpressionNode) node).getNode() instanceof BinaryOperatorNode){ - type = binaryoperator_type_check((BinaryOperatorNode) node); - } else if (((ExpressionNode) node).getNode() instanceof RelationsAndLogicalOperatorNode){ - type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) node); - } - } - return type; - } - - public void visit(WhileLoopNode node) { // ! Type cheking her er at checke expression while(expresion) sikre at det - // er en bool type - AstNode toCheck = (node.getExpression()).getNode(); - Type tocheck_type = Type.VOID; - - if (toCheck instanceof IdentifierNode) { - tocheck_type = getVariable((IdentifierNode) node.getExpression().getNode()); // skal evaluere til bool - } else if (toCheck instanceof RelationsAndLogicalOperatorNode) { - tocheck_type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) toCheck); // skal også til bool - } - if (toCheck instanceof BoolNode) { - tocheck_type = Type.BOOLEAN; - } - - if (tocheck_type != Type.BOOLEAN) { - System.out.println("While loop condition wrong type should be bool, but was:"+tocheck_type + "and got thi node"+toCheck); - } - HashMap localTable = new HashMap<>(); - scopes.add(localTable); - visit(node.getBlock()); - toCheck = visit(node.getExpression().getNode()); - scopes.remove(localTable); - - } +// HashMap fTable; // function table, identifier(x) og node +// HashMap ETable;// variable table, identifier(x) og node(int) +// Stack> scopes; // scope table, variable identifier(x) og node +// Deque activeScope;// Hvilket scope vi er i nu +// +// boolean printypes = true;// ! SLET SENERE +// +// public AstNode visit(AstNode node) { +// if (node instanceof ProgramNode) { +// if (printypes) { +// System.out.println("Hej jeg kommer int i visitor"); +// } +// fTable = new HashMap<>(); +// ETable = new HashMap<>(); +// scopes = new Stack<>(); +// activeScope = new ArrayDeque<>(); +// activeScope.push(0); +// scopes.add(ETable); +// +// return visit((ProgramNode) node); +// } else if (node instanceof StatementNode) { +// return visit((StatementNode) node); +// } else if (node instanceof ExpressionNode) { +// return visit((ExpressionNode) node); +// } +// return node; +// } +// +// public void visit(StatementNode node) { +// if (node.getNode() instanceof AssignmentNode) { +// visit((AssignmentNode) node.getNode()); +// } else if (node.getNode() instanceof VariableDeclarationNode) { +// visit((VariableDeclarationNode) node.getNode()); +// } else if (node.getNode() instanceof FunctionCallNode) { +// return visit((FunctionCallNode) node.getNode()); +// } else if (node.getNode() instanceof FunctionDefinitionNode) { +// return visit((FunctionDefinitionNode) node.getNode()); +// } else if (node.getNode() instanceof WhileLoopNode) { +// return visit((WhileLoopNode) node.getNode()); +// } else if (node.getNode() instanceof IfStatementNode) { +// visit((IfStatementNode) node.getNode()); +// } else if (node.getNode() instanceof BinaryOperatorNode) { +// visit((BinaryOperatorNode) node.getNode()); +// if (true) { +// System.out.println("Hej jeg kommer int i interpriter binaryoperator"); +// } +// } else if (node.getNode() instanceof ReturnStatementNode) { +// return visit((ReturnStatementNode) node.getNode()); +// } +// +// } +// +// public AstNode visit(ReturnStatementNode node) { +// return node; +// } +// +// public void visit(IfStatementNode node) { +// HashMap localTable = new HashMap<>(); // ny lokalt value table +// scopes.add(localTable); // Tilføjer det til stacken med scopes +// boolean visited = false; +// for (int i = 0; i < node.getExpressions().size(); i++) { // Hver expression er en if statement. Ligesom hver +// // block er til den if statement +// AstNode toCheck = node.getExpressions().get(i).getNode(); +// if (node.getExpressions().get(i).getNode() instanceof IdentifierNode) { +// toCheck = getVariable((IdentifierNode) node.getExpressions().get(i).getNode());// Hvis det er x så giv +// // mig xnode +// } else if (node.getExpressions().get(i).getNode() instanceof RelationsAndLogicalOperatorNode) { +// toCheck = visit((RelationsAndLogicalOperatorNode) node.getExpressions().get(i).getNode()); +// } +// if (toCheck instanceof BoolNode && ((BoolNode) toCheck).getValue()) { +// visit(node.getBlocks().get(i)); +// visited = true; +// break; +// } +// } +// if (!visited && node.getExpressions().size() < node.getBlocks().size()) { +// visit(node.getBlocks().get(node.getBlocks().size() - 1)); +// } +// scopes.remove(localTable); +// } +// +// public Type getVariable(IdentifierNode node) { +// // for (HashMap vTable : scopes) { +// if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { // Tester om x er der, ev til bool +// return scopes.getFirst().get(node.getIdentifier().toString());// i scope, giv mig x node +// } +// +// for (int i = activeScope.getLast(); i < scopes.size(); i++) {// for at gå igennem hvert scope og tjekke for x +// if (scopes.get(i).containsKey(node.getIdentifier().toString())) { +// return scopes.get(i).get(node.getIdentifier().toString());// i i scope, giv mig x node +// } +// } +// throw new RuntimeException("could not find the variable " + node.getIdentifier()); +// } +// +// public void visit(AssignmentNode node) { +// +// for (HashMap vTable : scopes) { +// if (vTable.containsKey(node.getIdentifier().toString())) { // tjek if variable x is scopes bool +// AstNode nodeToChange = vTable.get(node.getIdentifier().toString());// retunere node +// AstNode toChange = node.getValue(); // Højre side af assignmen x= tochange vil retunere node +// if (toChange instanceof BinaryOperatorNode) { +// toChange = visit((BinaryOperatorNode) toChange); // if x= 20+20 +// } +// if (toChange instanceof FunctionCallNode) { +// toChange = visit((FunctionCallNode) toChange); // if x= functioncall(10) +// } +// if (toChange instanceof IdentifierNode) { +// toChange = getVariable((IdentifierNode) toChange); // if x = y +// } +// if (node.getValue() instanceof RelationsAndLogicalOperatorNode) { // if x= 10<5 +// toChange = visit((RelationsAndLogicalOperatorNode) toChange); +// } +// AstNode finalToChange = toChange; +// switch (nodeToChange) { +// case IntNode intNode when finalToChange instanceof IntNode -> +// intNode.setValue(((IntNode) finalToChange).getValue()); +// case FloatNode floatNode when finalToChange instanceof FloatNode -> +// floatNode.setValue(((FloatNode) finalToChange).getValue()); +// case StringNode stringNode when finalToChange instanceof StringNode -> +// stringNode.setValue(((StringNode) finalToChange).getValue()); +// case BoolNode boolNode when finalToChange instanceof BoolNode -> +// boolNode.setValue(((BoolNode) finalToChange).getValue()); +// case null, default -> throw new RuntimeException("Type mismatch"); +// } +// return; +// } +// } +// +// throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); +// } +// +// public void visit(VariableDeclarationNode node) { +// boolean found = false; +// if (scopes.getFirst().containsKey(node.getIdentifier().toString())) {// finder x i scope FY FY +// found = true; +// } +// +// for (int i = activeScope.getLast(); i < scopes.size(); i++) {// finder x i et scope FY FY +// if (scopes.get(i).containsKey(node.getIdentifier().toString())) { +// found = true; +// } +// } +// if (!found) { // kunne ikke finde x i scope så kan gemme den +// +// AstNode toChange = node.getValue(); // x=value value = node eller 5 +// if (node.getValue() instanceof BinaryOperatorNode) { // hvis x=2+2 +// toChange = visit((BinaryOperatorNode) node.getValue()); // Henter type node efter operation node +// scopes.getLast().put(node.getIdentifier().toString(), toChange); // Her sætter vi x til type node i +// // scope hash map +// } else if (toChange instanceof IdentifierNode) { // Vis x=y +// for (HashMap vTable : scopes) {// For hvert scope skal vi prøve at finde variable +// if (vTable.containsKey(toChange.toString())) {// Vis vi finder den i et scope +// scopes.getLast().put(node.getIdentifier().toString(), vTable.get(toChange.toString())); +// } +// } +// } else { +// scopes.getLast().put(node.getIdentifier().toString(), toChange); // case hvor x=4 +// } +// +// } else { // Fy fy den findes allerede +// throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); +// } +// } +// +// public AstNode visit(TypeNode node) { +// return node; +// } +// +// public AstNode visit(BoolNode node) { +// return node; +// } +// +// public AstNode visit(IntNode node) { +// return node; +// } +// +// public AstNode visit(FloatNode node) { +// return node; +// } +// +// public AstNode visit(ProgramNode node) { +// for (AstNode statement : node.getStatements()) { +// visit(statement); +// } +// return node; +// } +// +// public void visit(FunctionCallNode node) { +// if (node.getFunctionName().toString().equals("print")) { +// InbuildClasses.print(node, scopes, activeScope); +// } else { +// HashMap localTable = new HashMap<>(); +// scopes.add(localTable); +// activeScope.add(scopes.size() - 1); +// +// if (fTable.containsKey(node.getFunctionName().toString())) { +// FunctionDefinitionNode function = fTable.get(node.getFunctionName().toString()); +// List arguments = function.getArguments().getParameters(); +// for (int i = 0; i < function.getArguments().getParameters().size(); i++) { +// visit(new VariableDeclarationNode(arguments.get(i).getIdentifier(), arguments.get(i).getType(), +// node.getArgument(i))); +// } +// AstNode test = visit(function.getBlock());//! Denne her skal have statements +// +// if (test instanceof ReturnStatementNode) { +// AstNode returnValue = ((ReturnStatementNode) test).getReturnValue(); +// if (returnValue instanceof IdentifierNode) { +// returnValue = getVariable((IdentifierNode) returnValue); +// } +// scopes.remove(localTable); +// activeScope.removeLast(); +// if (function.getReturnType().getType().equals("void")) { +// if (returnValue != null) { +// throw new RuntimeException( +// "cannot return a value in void function call or have code after return statement"); +// } +// return node; +// } +// +// return returnValue; +// } +// } +// } +// return node; +// } +// +// public void visit(BlockNode node) { +// for (AstNode statement : node.getStatements()) { +// +// if (((StatementNode) statement).getNode() instanceof ReturnStatementNode) { +// visit((StatementNode) statement); +// } else { +// visit((StatementNode) statement); +// } +// } +// } +// +// public void visit(ExpressionNode node) { +// if (node.getNode() instanceof FunctionCallNode) { +// visit((FunctionCallNode) node.getNode()); +// } else if (node.getNode() instanceof RelationsAndLogicalOperatorNode) { +// visit((RelationsAndLogicalOperatorNode) node.getNode()); +// } else if (node.getNode() instanceof BinaryOperatorNode) { +// visit((BinaryOperatorNode) node.getNode()); +// } +// } +// +// public void visit(FunctionDefinitionNode node) { +// if (!fTable.containsKey(node.getIdentifier().toString())) { +// fTable.put(node.getIdentifier().toString(), node); +// } else { +// throw new RuntimeException("function " + node.getIdentifier() + " already exists"); +// } +// } +// +// public Type binaryoperator_type_check(BinaryOperatorNode node) { +// AstNode left = node.getLeft(); // Får venstre x som i result=x+y i node form +// AstNode right = node.getRight();// Får højre y i node form +// +// Type left_type = Type.VOID; +// Type right_Type = Type.VOID; +// +// left_type = getType(left); +// right_Type = getType(right); +// +// // Lav type check her. +// +// if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. +// return Type.INT; +// } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { +// return Type.FLOAT; +// } +// System.out.println( +// "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); +// return Type.VOID; +// } +// +// public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { +// +// AstNode left = node.getLeft(); +// AstNode right = node.getRight(); +// +// Type left_type = Type.VOID; +// Type right_Type = Type.VOID; +// +// left_type = getType(left); +// right_Type = getType(right); +// +// if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. +// return Type.BOOLEAN; +// } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { +// return Type.BOOLEAN; +// } else if (left_type == Type.BOOLEAN && right_Type == Type.BOOLEAN) { +// return Type.BOOLEAN; +// } +// +// System.out.println( +// "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); +// return Type.VOID; +// } +// +// public Type getType(AstNode node) { +// Type type = Type.VOID; +// +// if (node instanceof IdentifierNode) { +// type = getVariable((IdentifierNode) node); // Vis x giv mig x value +// } else if (node instanceof BinaryOperatorNode) { +// type = binaryoperator_type_check((BinaryOperatorNode) node); +// } else if (node instanceof IntNode) { +// type = Type.INT; +// } else if (node instanceof FloatNode) { +// type = Type.FLOAT; +// } else if (node instanceof BoolNode) { +// type = Type.BOOLEAN; +// } else if (node instanceof ExpressionNode){ +// if(((ExpressionNode) node).getNode() instanceof BinaryOperatorNode){ +// type = binaryoperator_type_check((BinaryOperatorNode) node); +// } else if (((ExpressionNode) node).getNode() instanceof RelationsAndLogicalOperatorNode){ +// type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) node); +// } +// } +// return type; +// } +// +// public void visit(WhileLoopNode node) { // ! Type cheking her er at checke expression while(expresion) sikre at det +// // er en bool type +// AstNode toCheck = (node.getExpression()).getNode(); +// Type tocheck_type = Type.VOID; +// +// if (toCheck instanceof IdentifierNode) { +// tocheck_type = getVariable((IdentifierNode) node.getExpression().getNode()); // skal evaluere til bool +// } else if (toCheck instanceof RelationsAndLogicalOperatorNode) { +// tocheck_type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) toCheck); // skal også til bool +// } +// if (toCheck instanceof BoolNode) { +// tocheck_type = Type.BOOLEAN; +// } +// +// if (tocheck_type != Type.BOOLEAN) { +// System.out.println("While loop condition wrong type should be bool, but was:"+tocheck_type + "and got thi node"+toCheck); +// } +// HashMap localTable = new HashMap<>(); +// scopes.add(localTable); +// visit(node.getBlock()); +// toCheck = visit(node.getExpression().getNode()); +// scopes.remove(localTable); +// +// } } From 78fa85b2b54c5b2afac10c110871f538ebe5e2fa Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:13:27 +0200 Subject: [PATCH 17/94] A lot of shit works now Assignment virker type check Variable declaraition type check virker ish. virker med identtifieres og tal --- .../java/dk/aau/cs_24_sw_4_16/carl/Main.java | 2 +- .../carl/Semantic_A/SemanticAnalyzer.java | 2 +- .../carl/Semantic_A/TypeChecker.java | 163 ++++++++++++++---- test.carl | 63 +------ 4 files changed, 141 insertions(+), 89 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index 8285feb..1b39c6e 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -42,7 +42,7 @@ public static void main(String... args) { CstToAstVisitor visitor = new CstToAstVisitor(); // The visit method walks the parse tree and constructs the AST AstNode astRoot = visitor.visit(tree); - System.out.println(astRoot); + //System.out.println(astRoot); SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer(); semanticAnalyzer.analyze(astRoot); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java index 9bc7f52..1fd4b9e 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java @@ -3,7 +3,7 @@ import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; public class SemanticAnalyzer { - public boolean printTest = true; + public boolean printTest = false; public void analyze(AstNode root) throws SemanticException { if (printTest) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 2dbb981..24305cd 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -7,6 +7,8 @@ import java.util.HashMap; import java.util.Stack; +import javax.print.DocFlavor.STRING; + public class TypeChecker { HashMap fTable; // function table, identifier(x) og node HashMap ETable;// variable table, identifier(x) og node(int) @@ -38,63 +40,158 @@ public void visitStatements(StatementNode node) { if (node.getNode() instanceof VariableDeclarationNode) { visitVariableDeclaration((VariableDeclarationNode) node.getNode()); } + if (node.getNode() instanceof AssignmentNode) { + visitAssignNode((AssignmentNode) node.getNode()); + } } - private void visitVariableDeclaration(VariableDeclarationNode node) { - boolean found = scopes.getFirst().containsKey(node.getIdentifier().toString()); - for (int i = activeScope.getLast(); i < scopes.size(); i++) { - if (scopes.get(i).containsKey(node.getIdentifier().toString())) { - found = true; + try { + boolean found = scopes.getFirst().containsKey(node.getIdentifier().toString()); + + for (int i = activeScope.getLast(); i < scopes.size(); i++) { + if (scopes.get(i).containsKey(node.getIdentifier().toString())) { + found = true; + } } - } - if (!found) { - System.out.println("We in! " + node.getType()); - Type toChange = getType(node); - - if (node.getValue() instanceof BinaryOperatorNode) { - // toChange = visit((BinaryOperatorNode) node.getValue()); - - // scopes.getLast().put(node.getIdentifier().toString(), toChange); - } else if (node.getValue() instanceof IdentifierNode) { - for (HashMap ETable : scopes) { - if (ETable.containsKey(toChange.toString())) { - scopes.getLast().put(node.getIdentifier().toString(), ETable.get(toChange.toString())); + if (!found) {// Vi skal tjekke variable type mod det den type vi assigner til variablen. + + String identifier = node.getIdentifier().toString(); + + Type variableType = getType(node.getType()); // Left side type + + AstNode ass = node.getValue(); // THis is right side should be a node + Type assignmentType = getType(ass); // This should give right side type + + if (variableType == assignmentType) { + Type Type_we_save_in_E_table = variableType; + + if (node.getValue() instanceof BinaryOperatorNode) { + // toChange = visit((BinaryOperatorNode) node.getValue()); + + // scopes.getLast().put(node.getIdentifier().toString(), toChange); + } else if (node.getValue() instanceof IdentifierNode) { + for (HashMap ETable : scopes) { + if (ETable.containsKey(Type_we_save_in_E_table.toString())) { + scopes.getLast().put(node.getIdentifier().toString(), + ETable.get(Type_we_save_in_E_table.toString())); + } + } + } else { + scopes.getLast().put(node.getIdentifier().toString(), Type_we_save_in_E_table); } + } else { + System.out.println("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + + " that has the type:" + variableType + + " And that is hella iligal"); } } else { - scopes.getLast().put(node.getIdentifier().toString(), toChange); + throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); } + } catch (Exception e) { + System.out.println(e); + } - } else { - throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); + } + + public Type getVariable(IdentifierNode node) { + for (HashMap ETable : scopes) { + if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { + System.out.println("Get Varible ident:"+node.getIdentifier()); + System.out.println("Get Varible"+scopes.getFirst().get(node.getIdentifier().toString())); + return scopes.getFirst().get(node.getIdentifier().toString()); + } } + for (int i = activeScope.getLast(); i < scopes.size(); i++) { + if (scopes.get(i).containsKey(node.getIdentifier().toString())) { + System.out.println("Get Varible2"+scopes.getFirst().get(node.getIdentifier().toString())); + return scopes.get(i).get(node.getIdentifier().toString()); + } + } + System.out.println("could not find the variable: " + node.getIdentifier()); + throw new RuntimeException("could not find the variable " + node.getIdentifier()); + } + public void visitAssignNode(AssignmentNode node) { + + for (HashMap ETable : scopes) { + if (ETable.containsKey(node.getIdentifier().toString())) {// hvis x er i scope + // tjekke om det er lovligt. + // hent gamle type og nye type. + Type oldType = getType(node.getIdentifier()); + String identifier = node.getIdentifier().toString(); + System.out.println(oldType); + + Type rightType = getType(node.getValue()); + System.out.println("we get in hereaowidjawiodjwaoidja"); + // tjekke om det er lovligt. + if (oldType != rightType) { + System.out.println("Tryied to asssign Type:" + rightType + " to the variable:" + identifier + + " that has the type:" + oldType + + " And that is hella iligal"); + } + return; + } + } + + throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); + } - public Type getType(AstNode node) { + public Type getType(Object node) { Type type = Type.VOID; if (node instanceof IdentifierNode) { -// type = getVariable((IdentifierNode) node); // Vis x giv mig x value + type = getVariable((IdentifierNode) node); // Vis x giv mig x value } else if (node instanceof BinaryOperatorNode) { -// type = binaryoperator_type_check((BinaryOperatorNode) node); + // type = binaryoperator_type_check((BinaryOperatorNode) node); } else if (node instanceof IntNode) { - type = Type.INT; - System.out.println(((IntNode) node).getValue() + " We in intNode"); + IntNode intNode = (IntNode) node; + Object value = intNode.getValue(); + if (value instanceof Integer) { + type = Type.INT; + } } else if (node instanceof FloatNode) { type = Type.FLOAT; } else if (node instanceof BoolNode) { type = Type.BOOLEAN; - } else if (node instanceof ExpressionNode){ -// if(((ExpressionNode) node).getNode() instanceof BinaryOperatorNode){ -// type = binaryoperator_type_check((BinaryOperatorNode) node); -// } else if (((ExpressionNode) node).getNode() instanceof RelationsAndLogicalOperatorNode){ -// type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) node); -// } - } else if (false) { + } else if (node instanceof ExpressionNode) { + + } else if (node instanceof StringNode) { + System.out.println("We get into string node"); + type = Type.STRING; + } + + else if (node instanceof TypeNode) { + String type_fuck_me_why_did_we_save_types_as_String = ((TypeNode) node).getType(); + System.out.println(type_fuck_me_why_did_we_save_types_as_String + "get in gere"); + + switch (type_fuck_me_why_did_we_save_types_as_String) { + case "int": + + return Type.INT; + + case "string": + return Type.STRING; + default: + break; + } + + if (node instanceof String) { // Directly handling raw Strings + System.out.println("We get the string class raw string" + node); + return Type.STRING; + } else if (node instanceof Integer) { // Directly handling raw Integers + return Type.INT; + } else if (node instanceof Float) { // Directly handling raw Floats + return Type.FLOAT; + } else if (node instanceof Boolean) { // Directly handling raw Booleans + return Type.BOOLEAN; + } + + } else { + System.out.println("The node we get failed to handle:" + node.getClass()); } return type; } diff --git a/test.carl b/test.carl index 23145d0..ff8c5a5 100644 --- a/test.carl +++ b/test.carl @@ -1,58 +1,13 @@ // Valid test cases var c : int = 5 -var y : int = c -var d : int = 3 -var b : bool = true -c = (4 + 4) + 4 -print(c,"myC") -c = (d + d) + 5 -print(c,"My Second C") -c = (5 + d) * 5 -c = 3 + (d + 5) -print("Her starter Carls test") -var poop : int =2 -var poop2 : int =2 -var p : int = poop+poop2 +var p: int = "Hej" +var nej:string = "hej hej" +var sej :int = nej -print(p, "CARLS PRINT" ) +var k:int = 20 +c=10 -while d <= 5{ - print(d) - var b2 : int = d - print(b2, "got it") - d= d+1 -} -fn test (haha : int, baba : bool) -> void{ - print(haha) - print(baba) - test2(69,false) -} -fn test2 (haha : int, baba : bool) -> void{ - print(haha) - print(baba) -} -test(69420,true) -if false{ - print("false") -} -else if b{ - print("else if") - b = false - var holy : bool = false - if true{ - holy = false - print(holy) - } - if true{ - holy = true - print(holy) - } - if true{ - holy = false - print(holy) - } - if true{ - holy = true - print(holy) - } -} + +c=k // p bliver gemt + +k=nej \ No newline at end of file From 4f40bf9852e6efb9ff877b9f75ae1e7876936ad9 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:50:18 +0200 Subject: [PATCH 18/94] Binnary operations bliver nu sucefuldt checkket --- .../carl/Semantic_A/SemanticAnalyzer.java | 2 +- .../carl/Semantic_A/TypeChecker.java | 60 ++++++++++--------- test.carl | 3 +- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java index 1fd4b9e..3fe7dcf 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java @@ -13,7 +13,7 @@ public void analyze(AstNode root) throws SemanticException { TypeChecker typeChecker = new TypeChecker(); typeChecker.visitor(root); - +System.out.println("-----------------------------------------------"); System.out.println("Her stopper visitor class"); if (root != null) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 24305cd..c6103b9 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -45,6 +45,29 @@ public void visitStatements(StatementNode node) { } } + public Type binaryoperator_type_check(BinaryOperatorNode node) { + AstNode left = node.getLeft(); // Får venstre x som i result=x+y i node form + AstNode right = node.getRight();// Får højre y i node form + + Type left_type = Type.VOID; + Type right_Type = Type.VOID; + + left_type = getType(left); + right_Type = getType(right); + + if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. + return Type.INT; + + } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { + return Type.FLOAT; + } + + System.out.println( + "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); + return Type.VOID; + + } + private void visitVariableDeclaration(VariableDeclarationNode node) { try { @@ -66,21 +89,8 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { if (variableType == assignmentType) { Type Type_we_save_in_E_table = variableType; + scopes.getLast().put(node.getIdentifier().toString(), Type_we_save_in_E_table); - if (node.getValue() instanceof BinaryOperatorNode) { - // toChange = visit((BinaryOperatorNode) node.getValue()); - - // scopes.getLast().put(node.getIdentifier().toString(), toChange); - } else if (node.getValue() instanceof IdentifierNode) { - for (HashMap ETable : scopes) { - if (ETable.containsKey(Type_we_save_in_E_table.toString())) { - scopes.getLast().put(node.getIdentifier().toString(), - ETable.get(Type_we_save_in_E_table.toString())); - } - } - } else { - scopes.getLast().put(node.getIdentifier().toString(), Type_we_save_in_E_table); - } } else { System.out.println("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + " that has the type:" + variableType @@ -96,16 +106,15 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { } public Type getVariable(IdentifierNode node) { - for (HashMap ETable : scopes) { - if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { - System.out.println("Get Varible ident:"+node.getIdentifier()); - System.out.println("Get Varible"+scopes.getFirst().get(node.getIdentifier().toString())); - return scopes.getFirst().get(node.getIdentifier().toString()); - } + if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { + System.out.println("Get Varible ident:" + node.getIdentifier()); + System.out.println("Get Varible" + scopes.getFirst().get(node.getIdentifier().toString())); + return scopes.getFirst().get(node.getIdentifier().toString()); } + for (int i = activeScope.getLast(); i < scopes.size(); i++) { if (scopes.get(i).containsKey(node.getIdentifier().toString())) { - System.out.println("Get Varible2"+scopes.getFirst().get(node.getIdentifier().toString())); + System.out.println("Get Varible2" + scopes.getFirst().get(node.getIdentifier().toString())); return scopes.get(i).get(node.getIdentifier().toString()); } } @@ -122,10 +131,8 @@ public void visitAssignNode(AssignmentNode node) { // hent gamle type og nye type. Type oldType = getType(node.getIdentifier()); String identifier = node.getIdentifier().toString(); - System.out.println(oldType); Type rightType = getType(node.getValue()); - System.out.println("we get in hereaowidjawiodjwaoidja"); // tjekke om det er lovligt. if (oldType != rightType) { System.out.println("Tryied to asssign Type:" + rightType + " to the variable:" + identifier @@ -145,7 +152,7 @@ public Type getType(Object node) { if (node instanceof IdentifierNode) { type = getVariable((IdentifierNode) node); // Vis x giv mig x value } else if (node instanceof BinaryOperatorNode) { - // type = binaryoperator_type_check((BinaryOperatorNode) node); + type = binaryoperator_type_check((BinaryOperatorNode) node); } else if (node instanceof IntNode) { IntNode intNode = (IntNode) node; Object value = intNode.getValue(); @@ -161,12 +168,9 @@ public Type getType(Object node) { } else if (node instanceof StringNode) { System.out.println("We get into string node"); type = Type.STRING; - } - - else if (node instanceof TypeNode) { + } else if (node instanceof TypeNode) { String type_fuck_me_why_did_we_save_types_as_String = ((TypeNode) node).getType(); System.out.println(type_fuck_me_why_did_we_save_types_as_String + "get in gere"); - switch (type_fuck_me_why_did_we_save_types_as_String) { case "int": diff --git a/test.carl b/test.carl index ff8c5a5..97ec846 100644 --- a/test.carl +++ b/test.carl @@ -6,8 +6,9 @@ var sej :int = nej var k:int = 20 c=10 +var pp:int = 4+c - +pp= 5+nej c=k // p bliver gemt k=nej \ No newline at end of file From 22b3edfa743b1314b177e5f549bc03e20b6c510e Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:59:23 +0200 Subject: [PATCH 19/94] sidste ting --- .../carl/Semantic_A/TypeChecker.java | 26 +++++++++++++++++++ test.carl | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index c6103b9..2b58337 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -45,6 +45,32 @@ public void visitStatements(StatementNode node) { } } + + public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { + + AstNode left = node.getLeft(); + AstNode right = node.getRight(); + + Type left_type = Type.VOID; + Type right_Type = Type.VOID; + + left_type = getType(left); + right_Type = getType(right); + + if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. + return Type.BOOLEAN; + } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { + return Type.BOOLEAN; + } else if (left_type == Type.BOOLEAN && right_Type == Type.BOOLEAN) { + return Type.BOOLEAN; + } + + System.out.println( + "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); + return Type.VOID; + } + + public Type binaryoperator_type_check(BinaryOperatorNode node) { AstNode left = node.getLeft(); // Får venstre x som i result=x+y i node form AstNode right = node.getRight();// Får højre y i node form diff --git a/test.carl b/test.carl index 97ec846..213ce4e 100644 --- a/test.carl +++ b/test.carl @@ -10,5 +10,5 @@ var pp:int = 4+c pp= 5+nej c=k // p bliver gemt - +var bool:boolean = true k=nej \ No newline at end of file From 8927b1423a3d852186880edcaa3d8c9a9c481e1a Mon Sep 17 00:00:00 2001 From: MShadiF Date: Sat, 27 Apr 2024 15:15:39 +0200 Subject: [PATCH 20/94] Ifstatement checker lavet --- .../carl/Semantic_A/SemanticAnalyzer.java | 5 +- .../carl/Semantic_A/TypeChecker.java | 72 +++++++++++++++---- 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java index 3fe7dcf..8a80b90 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java @@ -3,7 +3,7 @@ import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; public class SemanticAnalyzer { - public boolean printTest = false; + public boolean printTest = true; public void analyze(AstNode root) throws SemanticException { if (printTest) { @@ -76,9 +76,10 @@ private void visit(AstNode node) throws SemanticException { } else if (node instanceof VariableDeclarationNode) { visitVariableDeclaration((VariableDeclarationNode) node); if (printTest) { - System.out.println("Hej jeg kommer ind i variable"); + System.out.println("Hej jeg kommer ind i variabledeclaration"); } } + // Add more as necessary } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 2b58337..63162f8 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -2,10 +2,7 @@ import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.HashMap; -import java.util.Stack; +import java.util.*; import javax.print.DocFlavor.STRING; @@ -43,19 +40,22 @@ public void visitStatements(StatementNode node) { if (node.getNode() instanceof AssignmentNode) { visitAssignNode((AssignmentNode) node.getNode()); } + if(node.getNode() instanceof IfStatementNode) { + visitIfStatement((IfStatementNode) node.getNode()); + } } public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { AstNode left = node.getLeft(); - AstNode right = node.getRight(); + AstNode right = node.getRight(); Type left_type = Type.VOID; Type right_Type = Type.VOID; left_type = getType(left); - right_Type = getType(right); + right_Type = getType(right); if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. return Type.BOOLEAN; @@ -66,7 +66,7 @@ public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { } System.out.println( - "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); + "Wrong types for relation operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); return Type.VOID; } @@ -126,7 +126,7 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); } } catch (Exception e) { - System.out.println(e); + System.out.println(e.getMessage()); } } @@ -172,6 +172,39 @@ public void visitAssignNode(AssignmentNode node) { throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); } +/* +* Vi her skal vi sikre af hver if(exp) exp = bool. i if statements har vi if if else flere exp som alle skal være type bool +* +* */ + + public void visitIfStatement(IfStatementNode node) { + HashMap localTable = new HashMap<>(); + scopes.add(localTable); + Type expression = Type.VOID; + System.out.println("FYcj this code i hate the oop it sucsk ass"); + for (int i = 0; i < node.getExpressions().size(); i++) { + expression = getType(node.getExpressions().get(i).getNode()); + System.out.println("this is expression:"+i+":"+node.getExpressions().get(i).getNode().getClass()); + if (expression != Type.BOOLEAN) { + System.out.println("If statements expresion must resolve to bool expresion, and this resolve to Type:" + expression); + } + } + for (int i = 0; i < node.getBlocks().size(); i++) { + visitBlockNode(node.getBlocks().get(i)); + + System.out.println(node.getBlocks().get(i)); + //Måske forkert, men det virker + scopes.remove(localTable); + } +// scopes.remove(localTable); + } + + public void visitBlockNode(BlockNode node) { + for (AstNode statement : node.getStatements()) { + visitStatements((StatementNode) statement); + } + } + public Type getType(Object node) { Type type = Type.VOID; @@ -179,12 +212,20 @@ public Type getType(Object node) { type = getVariable((IdentifierNode) node); // Vis x giv mig x value } else if (node instanceof BinaryOperatorNode) { type = binaryoperator_type_check((BinaryOperatorNode) node); - } else if (node instanceof IntNode) { + } else if (node instanceof RelationsAndLogicalOperatorNode){ + type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) node); + } +// else if (node instanceof ExpressionNode) { +// if (((ExpressionNode) node).getNode() instanceof BinaryOperatorNode) { +// type = binaryoperator_type_check((BinaryOperatorNode) node); +// } else if (((ExpressionNode) node).getNode() instanceof RelationsAndLogicalOperatorNode) { +// type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) node); +// } +// } + else if (node instanceof IntNode) { IntNode intNode = (IntNode) node; Object value = intNode.getValue(); - if (value instanceof Integer) { - type = Type.INT; - } + type = Type.INT; } else if (node instanceof FloatNode) { type = Type.FLOAT; } else if (node instanceof BoolNode) { @@ -199,12 +240,13 @@ public Type getType(Object node) { System.out.println(type_fuck_me_why_did_we_save_types_as_String + "get in gere"); switch (type_fuck_me_why_did_we_save_types_as_String) { case "int": - return Type.INT; - case "string": return Type.STRING; - + case "bool": + return Type.BOOLEAN; + case "float": + return Type.FLOAT; default: break; } From 56d49e9fd4215f601f9be769f3b940b6077e001a Mon Sep 17 00:00:00 2001 From: MShadiF Date: Sat, 27 Apr 2024 16:39:55 +0200 Subject: [PATCH 21/94] This is the corrected version, so each time it enters a new if-else statement it gets rid of the last one --- .../dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 63162f8..39fa366 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -178,8 +178,6 @@ public void visitAssignNode(AssignmentNode node) { * */ public void visitIfStatement(IfStatementNode node) { - HashMap localTable = new HashMap<>(); - scopes.add(localTable); Type expression = Type.VOID; System.out.println("FYcj this code i hate the oop it sucsk ass"); for (int i = 0; i < node.getExpressions().size(); i++) { @@ -190,6 +188,8 @@ public void visitIfStatement(IfStatementNode node) { } } for (int i = 0; i < node.getBlocks().size(); i++) { + HashMap localTable = new HashMap<>(); + scopes.add(localTable); visitBlockNode(node.getBlocks().get(i)); System.out.println(node.getBlocks().get(i)); From c2ea3d5787171e3a0e50238b5015a5c315ce75da Mon Sep 17 00:00:00 2001 From: MShadiF Date: Sun, 28 Apr 2024 15:15:29 +0200 Subject: [PATCH 22/94] CFG update --- src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 b/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 index 668b8bf..fb5d644 100644 --- a/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 +++ b/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 @@ -104,7 +104,7 @@ coordinateDeclaration : 'var' IDENTIFIER ':' 'coord' '=' '(' expression ',' expr INT : [-]?[0-9]+ ; FLOAT : [-]?[0-9]* '.' [0-9]+ ; STRING : '"' ~["]* '"' ; -BOOL : ('true' | 'false') ; +BOOL : '\b(true|false)\b' ; IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_]* ; WS : [ \t\r\n]+ -> skip ; LINE_COMMENT : '//' ~[\r\n]* -> skip ; \ No newline at end of file From f871c85258719bc087c056e218ce318a127f096a Mon Sep 17 00:00:00 2001 From: MShadiF Date: Sun, 28 Apr 2024 15:39:04 +0200 Subject: [PATCH 23/94] While loop type checker virker --- .../carl/Semantic_A/TypeChecker.java | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 39fa366..139ee88 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -43,6 +43,9 @@ public void visitStatements(StatementNode node) { if(node.getNode() instanceof IfStatementNode) { visitIfStatement((IfStatementNode) node.getNode()); } + if (node.getNode() instanceof WhileLoopNode) { + visitWhileLoop((WhileLoopNode) node.getNode()); + } } @@ -65,7 +68,7 @@ public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { return Type.BOOLEAN; } - System.out.println( + System.err.println( "Wrong types for relation operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); return Type.VOID; } @@ -88,7 +91,7 @@ public Type binaryoperator_type_check(BinaryOperatorNode node) { return Type.FLOAT; } - System.out.println( + System.err.println( "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); return Type.VOID; @@ -118,7 +121,7 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { scopes.getLast().put(node.getIdentifier().toString(), Type_we_save_in_E_table); } else { - System.out.println("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + System.err.println("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + " that has the type:" + variableType + " And that is hella iligal"); } @@ -126,7 +129,7 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); } } catch (Exception e) { - System.out.println(e.getMessage()); + System.err.println(e.getMessage()); } } @@ -144,7 +147,7 @@ public Type getVariable(IdentifierNode node) { return scopes.get(i).get(node.getIdentifier().toString()); } } - System.out.println("could not find the variable: " + node.getIdentifier()); + System.err.println("could not find the variable: " + node.getIdentifier()); throw new RuntimeException("could not find the variable " + node.getIdentifier()); } @@ -161,7 +164,7 @@ public void visitAssignNode(AssignmentNode node) { Type rightType = getType(node.getValue()); // tjekke om det er lovligt. if (oldType != rightType) { - System.out.println("Tryied to asssign Type:" + rightType + " to the variable:" + identifier + System.err.println("Tryied to asssign Type:" + rightType + " to the variable:" + identifier + " that has the type:" + oldType + " And that is hella iligal"); } @@ -179,12 +182,10 @@ public void visitAssignNode(AssignmentNode node) { public void visitIfStatement(IfStatementNode node) { Type expression = Type.VOID; - System.out.println("FYcj this code i hate the oop it sucsk ass"); for (int i = 0; i < node.getExpressions().size(); i++) { expression = getType(node.getExpressions().get(i).getNode()); - System.out.println("this is expression:"+i+":"+node.getExpressions().get(i).getNode().getClass()); if (expression != Type.BOOLEAN) { - System.out.println("If statements expresion must resolve to bool expresion, and this resolve to Type:" + expression); + System.err.println("If statements expresion must resolve to bool expresion, and this resolve to Type:" + expression); } } for (int i = 0; i < node.getBlocks().size(); i++) { @@ -193,10 +194,20 @@ public void visitIfStatement(IfStatementNode node) { visitBlockNode(node.getBlocks().get(i)); System.out.println(node.getBlocks().get(i)); - //Måske forkert, men det virker scopes.remove(localTable); } -// scopes.remove(localTable); + } + + public void visitWhileLoop(WhileLoopNode node) { + Type toCheck = getType((node.getExpression()).getNode()); + if (toCheck != Type.BOOLEAN) { + System.err.println("Condition type is not boolean"); + } + HashMap localTable = new HashMap<>(); + scopes.add(localTable); + visitBlockNode(node.getBlock()); + System.out.println(node.getBlock()); + scopes.remove(localTable); } public void visitBlockNode(BlockNode node) { @@ -263,7 +274,7 @@ else if (node instanceof IntNode) { } } else { - System.out.println("The node we get failed to handle:" + node.getClass()); + System.err.println("The node we get failed to handle:" + node.getClass()); } return type; } From baa8fc3b5d72277a2f87e1f02fbd0d3e2cff9ebb Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Mon, 29 Apr 2024 09:21:20 +0200 Subject: [PATCH 24/94] mini Fix true er for some reason en identifier cfg might have error. --- .../carl/Semantic_A/TypeChecker.java | 45 ++++++++++--------- test.carl | 10 ++++- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 139ee88..92d3e8b 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -40,7 +40,7 @@ public void visitStatements(StatementNode node) { if (node.getNode() instanceof AssignmentNode) { visitAssignNode((AssignmentNode) node.getNode()); } - if(node.getNode() instanceof IfStatementNode) { + if (node.getNode() instanceof IfStatementNode) { visitIfStatement((IfStatementNode) node.getNode()); } if (node.getNode() instanceof WhileLoopNode) { @@ -48,11 +48,10 @@ public void visitStatements(StatementNode node) { } } - public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { - AstNode left = node.getLeft(); - AstNode right = node.getRight(); + AstNode left = node.getLeft(); + AstNode right = node.getRight(); Type left_type = Type.VOID; Type right_Type = Type.VOID; @@ -73,7 +72,6 @@ public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { return Type.VOID; } - public Type binaryoperator_type_check(BinaryOperatorNode node) { AstNode left = node.getLeft(); // Får venstre x som i result=x+y i node form AstNode right = node.getRight();// Får højre y i node form @@ -114,6 +112,7 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { Type variableType = getType(node.getType()); // Left side type AstNode ass = node.getValue(); // THis is right side should be a node + System.out.println("Right side on declaration:" + ass.getClass()); Type assignmentType = getType(ass); // This should give right side type if (variableType == assignmentType) { @@ -175,17 +174,19 @@ public void visitAssignNode(AssignmentNode node) { throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); } -/* -* Vi her skal vi sikre af hver if(exp) exp = bool. i if statements har vi if if else flere exp som alle skal være type bool -* -* */ + /* + * Vi her skal vi sikre af hver if(exp) exp = bool. i if statements har vi if if + * else flere exp som alle skal være type bool + * + */ public void visitIfStatement(IfStatementNode node) { Type expression = Type.VOID; for (int i = 0; i < node.getExpressions().size(); i++) { expression = getType(node.getExpressions().get(i).getNode()); if (expression != Type.BOOLEAN) { - System.err.println("If statements expresion must resolve to bool expresion, and this resolve to Type:" + expression); + System.err.println("If statements expresion must resolve to bool expresion, and this resolve to Type:" + + expression); } } for (int i = 0; i < node.getBlocks().size(); i++) { @@ -201,7 +202,8 @@ public void visitIfStatement(IfStatementNode node) { public void visitWhileLoop(WhileLoopNode node) { Type toCheck = getType((node.getExpression()).getNode()); if (toCheck != Type.BOOLEAN) { - System.err.println("Condition type is not boolean"); + System.err.println( + "While loop expresion must resolve to bool expresion, and this resolve to Type:" + toCheck); } HashMap localTable = new HashMap<>(); scopes.add(localTable); @@ -220,19 +222,19 @@ public Type getType(Object node) { Type type = Type.VOID; if (node instanceof IdentifierNode) { - type = getVariable((IdentifierNode) node); // Vis x giv mig x value + System.out.println(node.toString()); + if ("true".equals(node.toString()) || "false".equals(node.toString())) { + type = Type.BOOLEAN; + } else { + type = getVariable((IdentifierNode) node); // Vis x giv mig x value + } + } else if (node instanceof BinaryOperatorNode) { type = binaryoperator_type_check((BinaryOperatorNode) node); - } else if (node instanceof RelationsAndLogicalOperatorNode){ + } else if (node instanceof RelationsAndLogicalOperatorNode) { type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) node); } -// else if (node instanceof ExpressionNode) { -// if (((ExpressionNode) node).getNode() instanceof BinaryOperatorNode) { -// type = binaryoperator_type_check((BinaryOperatorNode) node); -// } else if (((ExpressionNode) node).getNode() instanceof RelationsAndLogicalOperatorNode) { -// type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) node); -// } -// } + else if (node instanceof IntNode) { IntNode intNode = (IntNode) node; Object value = intNode.getValue(); @@ -240,6 +242,7 @@ else if (node instanceof IntNode) { } else if (node instanceof FloatNode) { type = Type.FLOAT; } else if (node instanceof BoolNode) { + System.out.println("Returns Bool type"); type = Type.BOOLEAN; } else if (node instanceof ExpressionNode) { @@ -248,7 +251,7 @@ else if (node instanceof IntNode) { type = Type.STRING; } else if (node instanceof TypeNode) { String type_fuck_me_why_did_we_save_types_as_String = ((TypeNode) node).getType(); - System.out.println(type_fuck_me_why_did_we_save_types_as_String + "get in gere"); + System.out.println("A :" + type_fuck_me_why_did_we_save_types_as_String + " :got in Here"); switch (type_fuck_me_why_did_we_save_types_as_String) { case "int": return Type.INT; diff --git a/test.carl b/test.carl index 213ce4e..4bf01d8 100644 --- a/test.carl +++ b/test.carl @@ -10,5 +10,11 @@ var pp:int = 4+c pp= 5+nej c=k // p bliver gemt -var bool:boolean = true -k=nej \ No newline at end of file +k=nej + +var b : bool = true + +var expression_true:bool =true +if expression_true { + sej = nej +} \ No newline at end of file From 71aa657b235a9b7c1a900fc3f98440ec1f464f23 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Mon, 29 Apr 2024 09:35:12 +0200 Subject: [PATCH 25/94] Bedre error forklaring --- .../java/dk/aau/cs_24_sw_4_16/carl/Main.java | 3 ++- .../carl/Semantic_A/TypeChecker.java | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index 5f59d57..e385dac 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -44,7 +44,8 @@ public static void main(String... args) { // The visit method walks the parse tree and constructs the AST AstNode astRoot = visitor.visit(tree); //System.out.println(astRoot); - + System.out.println(astRoot); + SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer(); semanticAnalyzer.analyze(astRoot); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 92d3e8b..1520dd8 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -11,7 +11,7 @@ public class TypeChecker { HashMap ETable;// variable table, identifier(x) og node(int) Stack> scopes; // scope table, variable identifier(x) og node Deque activeScope;// Hvilket scope vi er i nu - + int error =1; public TypeChecker() { fTable = new HashMap<>(); ETable = new HashMap<>(); @@ -66,7 +66,9 @@ public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { } else if (left_type == Type.BOOLEAN && right_Type == Type.BOOLEAN) { return Type.BOOLEAN; } - + + System.out.println("Error:"+error); + error = error+1; System.err.println( "Wrong types for relation operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); return Type.VOID; @@ -88,7 +90,8 @@ public Type binaryoperator_type_check(BinaryOperatorNode node) { } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { return Type.FLOAT; } - + System.out.println("Error:"+error); + error = error+1; System.err.println( "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); return Type.VOID; @@ -120,6 +123,8 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { scopes.getLast().put(node.getIdentifier().toString(), Type_we_save_in_E_table); } else { + System.out.println("Error:"+error); + error = error+1; System.err.println("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + " that has the type:" + variableType + " And that is hella iligal"); @@ -135,8 +140,8 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { public Type getVariable(IdentifierNode node) { if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { - System.out.println("Get Varible ident:" + node.getIdentifier()); - System.out.println("Get Varible" + scopes.getFirst().get(node.getIdentifier().toString())); + System.out.print("Get Varible identifier:" + node.getIdentifier()); + System.out.println(": Get Varible type:" + scopes.getFirst().get(node.getIdentifier().toString())); return scopes.getFirst().get(node.getIdentifier().toString()); } @@ -163,6 +168,8 @@ public void visitAssignNode(AssignmentNode node) { Type rightType = getType(node.getValue()); // tjekke om det er lovligt. if (oldType != rightType) { + System.out.println("Error:"+error); + error = error+1; System.err.println("Tryied to asssign Type:" + rightType + " to the variable:" + identifier + " that has the type:" + oldType + " And that is hella iligal"); From 9ff2c00f8c12d5104deac8bc6b2be730cd2ffa91 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Mon, 29 Apr 2024 10:04:24 +0200 Subject: [PATCH 26/94] Yes --- .../carl/Semantic_A/SemanticAnalyzer.java | 2 +- .../carl/Semantic_A/TypeChecker.java | 33 ++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java index 8a80b90..bb65d4c 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java @@ -3,7 +3,7 @@ import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; public class SemanticAnalyzer { - public boolean printTest = true; + public boolean printTest = false; public void analyze(AstNode root) throws SemanticException { if (printTest) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 1520dd8..3e4afa2 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -12,6 +12,7 @@ public class TypeChecker { Stack> scopes; // scope table, variable identifier(x) og node Deque activeScope;// Hvilket scope vi er i nu int error =1; + Boolean print_debugger = true; public TypeChecker() { fTable = new HashMap<>(); ETable = new HashMap<>(); @@ -34,6 +35,11 @@ public void visitProgramNode(ProgramNode node) { } public void visitStatements(StatementNode node) { + if(print_debugger){ + System.out.println("We get in the vist statement"); + System.out.println(node.getClass()); + System.out.println(node.getNode().getClass()); + } if (node.getNode() instanceof VariableDeclarationNode) { visitVariableDeclaration((VariableDeclarationNode) node.getNode()); } @@ -157,8 +163,15 @@ public Type getVariable(IdentifierNode node) { } public void visitAssignNode(AssignmentNode node) { - + if(print_debugger){ + System.out.println("Scopes:"+scopes); + System.out.println("Value"+node.getValue()); + } for (HashMap ETable : scopes) { + if(print_debugger){ + System.out.println("Identifier"+node.getIdentifier().toString()); + System.out.println("Etable:"+ETable); + } if (ETable.containsKey(node.getIdentifier().toString())) {// hvis x er i scope // tjekke om det er lovligt. // hent gamle type og nye type. @@ -166,6 +179,7 @@ public void visitAssignNode(AssignmentNode node) { String identifier = node.getIdentifier().toString(); Type rightType = getType(node.getValue()); + // tjekke om det er lovligt. if (oldType != rightType) { System.out.println("Error:"+error); @@ -189,7 +203,16 @@ public void visitAssignNode(AssignmentNode node) { public void visitIfStatement(IfStatementNode node) { Type expression = Type.VOID; + if(print_debugger){ + System.out.println("We get in the If statement"); + } + for (int i = 0; i < node.getExpressions().size(); i++) { + + if(print_debugger){ + System.out.println("We get in first for loop"); + System.out.println("Number of expressions:"+node.getExpressions().size()); + } expression = getType(node.getExpressions().get(i).getNode()); if (expression != Type.BOOLEAN) { System.err.println("If statements expresion must resolve to bool expresion, and this resolve to Type:" @@ -197,6 +220,10 @@ public void visitIfStatement(IfStatementNode node) { } } for (int i = 0; i < node.getBlocks().size(); i++) { + if(print_debugger){ + System.out.println("We get in 2 for loop"); + System.out.println("Number of blocks:"+node.getBlocks().size()); + } HashMap localTable = new HashMap<>(); scopes.add(localTable); visitBlockNode(node.getBlocks().get(i)); @@ -220,6 +247,10 @@ public void visitWhileLoop(WhileLoopNode node) { } public void visitBlockNode(BlockNode node) { + if(true){ + System.out.println("We get in vissitblock for loop"); + System.out.println("Number of statements:"+node.getStatements().size()); + } for (AstNode statement : node.getStatements()) { visitStatements((StatementNode) statement); } From 0766c33801888a247b1f51b9b0d38b35b08f8acb Mon Sep 17 00:00:00 2001 From: mantarias <32459446+mantarias@users.noreply.github.com> Date: Mon, 29 Apr 2024 12:56:15 +0200 Subject: [PATCH 27/94] some testing done for seed and intire inbuild function order --- map.json | 49 ++++ .../antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 | 1 + .../carl/Interpreter/InbuildClasses.java | 25 +- .../carl/Interpreter/Interpreter.java | 6 +- .../carl/SimpleFunctionIntegrationTest.java | 237 ++++++++++++++++-- test.carl | 67 +---- 6 files changed, 295 insertions(+), 90 deletions(-) create mode 100644 map.json diff --git a/map.json b/map.json new file mode 100644 index 0000000..081d291 --- /dev/null +++ b/map.json @@ -0,0 +1,49 @@ +{"map" : { + "size":{ + "height" : 10, + "width" : 10 + }, + "tiles": [ + +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","f","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","f","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","f","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","p","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}], +"level" : 1, +"type" : "Room", +"tileInformation":[ +{ +"symbol" : "w" , +"info" : { + "name" : "Wall" + } +}, +{ +"symbol" : "f" , +"info" : { + "name" : "Floor" + } +}, +{ +"symbol" : "p" , +"info" : { + "name" : "Player" + } +} +]}} \ No newline at end of file diff --git a/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 b/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 index 40cf68d..ce94569 100644 --- a/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 +++ b/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 @@ -44,6 +44,7 @@ structType : 'enemy' | 'floor' | 'wall' + | 'room' ; diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java index 4efe8f2..f95ecc2 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java @@ -146,14 +146,16 @@ public static void generateSpawns(FunctionCallNode node, Stack> scopes, HashMap> tileInformationFloor, HashMap> tileInformationWall, HashMap> tileInformationEnemy) { + public static void printMap(Stack> scopes, HashMap> tileInformationFloor, HashMap> tileInformationWall, HashMap> tileInformationEnemy) { - System.out.println(generatePrint(scopes,tileInformationFloor,tileInformationWall,tileInformationEnemy)); + System.out.println(generatePrint(scopes, tileInformationFloor, tileInformationWall, tileInformationEnemy)); } + public static void writeToFile(FunctionCallNode node, Stack> scopes, HashMap> tileInformationFloor, HashMap> tileInformationWall, HashMap> tileInformationEnemy) throws IOException { - Files.writeString(Path.of("map.json"), generatePrint(scopes,tileInformationFloor,tileInformationWall,tileInformationEnemy)); + Files.writeString(Path.of("map.json"), generatePrint(scopes, tileInformationFloor, tileInformationWall, tileInformationEnemy)); } - private static String generatePrint(Stack> scopes, HashMap> tileInformationFloor, HashMap> tileInformationWall, HashMap> tileInformationEnemy){ + + private static String generatePrint(Stack> scopes, HashMap> tileInformationFloor, HashMap> tileInformationWall, HashMap> tileInformationEnemy) { ArrayNode map = ((ArrayNode) scopes.getFirst().get("map")); StringBuilder sb = new StringBuilder(""" {"map" : { @@ -223,6 +225,7 @@ private static String generatePrint(Stack> scopes, Hash sb.append("]}}"); return sb.toString(); } + private static void tileInformationStringBuilder(HashMap> tileInformation, StringBuilder sb) { for (String name : tileInformation.keySet()) { for (HashMap innerHashMap : tileInformation.values()) { @@ -268,4 +271,18 @@ private static boolean overlap(int x, int y, int width, int height, ArrayNode ma } return false; } + + public static void setSeed(FunctionCallNode node) { + if (node.getArguments().size() == 1) { + if (node.getArgument(0) instanceof IntNode) { + Interpreter.rand = new Random(((IntNode) node.getArgument(0)).getValue()); + } else { + throw new RuntimeException("setSeed only supports int arguments"); + } + } else if (node.getArguments().isEmpty()) { + Interpreter.rand = new Random(); + } else { + throw new RuntimeException("setSeed called accepts only a singular int argument or none"); + } + } } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java index 9a7783f..dfcbf78 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java @@ -392,14 +392,16 @@ public AstNode visit(FunctionCallNode node) { InbuildClasses.generateSpawns(node, scopes, tileInformationEnemy, rooms); } else if (node.getFunctionName().toString().equals("printMap")) { InbuildClasses.printMap(scopes, tileInformationFloor, tileInformationWall, tileInformationEnemy); - } else if(node.getFunctionName().toString().equals("writeToFile")){ + } else if (node.getFunctionName().toString().equals("writeToFile")) { try { InbuildClasses.writeToFile(node, scopes, tileInformationFloor, tileInformationWall, tileInformationEnemy); } catch (IOException e) { throw new RuntimeException(e); } - }else { + } else if (node.getFunctionName().toString().equals("setSeed")) { + InbuildClasses.setSeed(node); + } else { HashMap localTable = new HashMap<>(); scopes.add(localTable); activeScope.add(scopes.size() - 1); diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java index 13eaf8b..773a21b 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java @@ -15,6 +15,7 @@ import java.io.InputStream; import java.io.PrintStream; import java.nio.charset.StandardCharsets; + import static org.junit.jupiter.api.Assertions.*; public class SimpleFunctionIntegrationTest { @@ -34,8 +35,8 @@ public void restoreStreams() { @Test public void testingPrintSatement() throws Exception { String code = """ - print("test") - """; + print("test") + """; InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); @@ -54,10 +55,10 @@ public void testingPrintSatement() throws Exception { @Test public void testingVariable() throws Exception { String code = """ - var x : int = 42 - var y : int = x - print(y) - """; + var x : int = 42 + var y : int = x + print(y) + """; InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); @@ -99,9 +100,9 @@ public void testingIncrementOperator() throws Exception { @Test public void testingAddition() throws Exception { String code = """ - var x : int = (1 + 2) - 2 - print(x) - """; + var x : int = (1 + 2) - 2 + print(x) + """; InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); @@ -175,12 +176,13 @@ public void testingIfElseChain() throws Exception { // Assertions can be extended based on the print output or internal state checks assertEquals("3".trim(), outContent.toString().trim(), "Expected the output to be 3 because x does not meet the other conditions and therefore, y should be set to 3."); } + @Test public void testingMult() throws Exception { String code = """ - var x : int = (1 * 4) / 2 - print(x) - """; + var x : int = (1 * 4) / 2 + print(x) + """; InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); @@ -225,12 +227,12 @@ public void testingWhile() throws Exception { @Test public void testingFunction() throws Exception { String code = """ - fn calculate() -> int { - return 42 - } - var result: int = calculate() - print(result) - """; + fn calculate() -> int { + return 42 + } + var result: int = calculate() + print(result) + """; InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); @@ -421,6 +423,205 @@ public void testingBool() throws Exception { // assertEquals("true", outContent.toString().trim(), "Expected the output to be true because 3 < 4."); // } + @Test + public void testingSeed() throws Exception { + String code = """ + setSeed(42069) + var test : int = 1..20 + print(test) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + + assertEquals("14".trim(), outContent.toString().trim()); + } + + @Test + public void testingSeed2() throws Exception { + String code = """ + setSeed(555) + var test : int = 1..20 + print(test) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + + assertEquals("6".trim(), outContent.toString().trim()); + } + + + @Test + public void testingEntireProcedure() throws Exception { + String code = """ + setSeed(42069) + generateMap(20,25) + generateRooms(3,5,7) + generateCorridors() + generateSpawns() + printMap() + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + +// do not touch the indentation of the check it will break + assertEquals(""" +{"map" : { + "size":{ + "height" : 10, + "width" : 10 + }, + "tiles": [ + +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","p","f","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w"]}, +{"row":["w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w","f","f","f","f","f","f","w","w","w"]}, +{"row":["w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w","f","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","f","f","f","f","f","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","f","f","f","f","f","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","f","f","f","f","f","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","f","f","f","f","f","f","f","f","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}], +"level" : 1, +"type" : "Room", +"tileInformation":[ +{ +"symbol" : "w" , +"info" : { + "name" : "Wall" + } +}, +{ +"symbol" : "f" , +"info" : { + "name" : "Floor" + } +}, +{ +"symbol" : "p" , +"info" : { + "name" : "Player" + } +} +]}} + """.trim(), outContent.toString().trim()); + } + + + //* +++++++++++++++++++++++ DONT YOU DARE TOUCH THIS TEST +++++++++++++++++++++ *// + @Test + public void testingEntireProcedure2() throws Exception { + String code = """ +setSeed(242) +generateMap(20,25) +generateRooms(3,5,7) +generateCorridors() +generateSpawns() +printMap() + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + Interpreter interpreter = new Interpreter(); + interpreter.visit(astRoot); + + + assertEquals(""" +{"map" : { + "size":{ + "height" : 10, + "width" : 10 + }, + "tiles": [ + +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","f","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","f","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","f","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","w","w","w","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","p","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w"]}, +{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}], +"level" : 1, +"type" : "Room", +"tileInformation":[ +{ +"symbol" : "w" , +"info" : { + "name" : "Wall" + } +}, +{ +"symbol" : "f" , +"info" : { + "name" : "Floor" + } +}, +{ +"symbol" : "p" , +"info" : { + "name" : "Player" + } +} +]}} +""".trim(), outContent.toString().trim()); + } } diff --git a/test.carl b/test.carl index 4368cd0..b719b9e 100644 --- a/test.carl +++ b/test.carl @@ -1,70 +1,5 @@ -// Valid test cases -//var c : int = 5 -//var y : int = c -//var d : int = 3 -//var b : bool = true -//c = (4 + 4) + 4 -//print(c,"myC") -//c = (d + d) + 5 -//print(c,"My Second C") -//c = (5 + d) * 5 -//c = 3 + (d + 5) -// -//while d <= 5{ -// print(d) -// var b2 : int = d -// print(b2, "got it") -// d= d+1 -//} -//fn test (haha : int, baba : bool) -> void{ -// print(haha) -// print(baba) -// test2(69,false) -//} -//fn test2 (haha : int, baba : bool) -> void{ -// print(haha) -// print(baba) -//} -//test(69420,true) -//if false{ -// print("false") -//} -//else if b{ -// print("else if") -// b = false -// var holy : bool = false -// if true{ -// holy = false -// print(holy) -// } -// if true{ -// holy = true -// print(holy) -// } -// if true{ -// holy = false -// print(holy) -// } -// if true{ -// holy = true -// print(holy) -// } -//} -//var Orc : enemy = { -// var difficulty : int = 1 -// var health : int = 200 -// var symbol : string= "O" -//} -//var Goblin : enemy ={ -// var difficulty : int = 1 -// var health : int = 500 -// var symbol : string= "O" -//} -//var test : int = 5 -//test = enemy.get(1).health -//print(test) +setSeed(242) generateMap(20,25) -var test : string = map[0][0] generateRooms(3,5,7) generateCorridors() generateSpawns() From ad02a843bb43e81b8d295d15922ba3c9fecb73e6 Mon Sep 17 00:00:00 2001 From: mantarias <32459446+mantarias@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:36:53 +0200 Subject: [PATCH 28/94] stuff for rooms --- .../carl/Interpreter/Interpreter.java | 48 +++++++++---------- test.carl | 16 ++++--- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java index dfcbf78..e44f30f 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java @@ -44,13 +44,33 @@ public AstNode visit(AstNode node) { } return node; } - + public AstNode roomCall(MethodCallNode node) + { + if (node.getPropertyAccessContext().getIdentifiers().get(0).toString().equals("size")) { + return new IntNode(rooms.size()); + } else if (node.getPropertyAccessContext().getIdentifiers().get(0).toString().equals("get")) { + if (((ArgumentListNode) node.getValue()).getList().get(0) instanceof IntNode) { + int index = ((IntNode) ((ArgumentListNode) node.getValue()).getList().get(0)).getValue(); + if (index < rooms.size()) { + return rooms.get(((IntNode) ((ArgumentListNode) node.getValue()).getList().get(0)).getValue()).get(node.getIdentifierNode().toString()); + } else { + throw new RuntimeException("out of bounds"); + } + } else { + throw new RuntimeException("parameter must be an int"); + } + } + throw new RuntimeException("method call went wrong"); + } public AstNode visit(MethodCallNode node) { HashMap> list; switch (node.getPropertyAccessContext().getList()) { case "enemy" -> list = tileInformationEnemy; case "wall" -> list = tileInformationWall; case "floor" -> list = tileInformationFloor; + case "room" -> { + return roomCall(node); + } default -> throw new RuntimeException("list doesnt exist"); } if (node.getPropertyAccessContext().getIdentifiers().get(0).toString().equals("size")) { @@ -115,6 +135,8 @@ public void visit(StructureDefinitionNode node) { tileInformationWall.put(node.getIdentifier().toString(), object); } else if (node.getType().equals("floor")) { tileInformationFloor.put(node.getIdentifier().toString(), object); + } else if (node.getType().equals("room")) { + rooms.add(object); } } @@ -225,30 +247,6 @@ public void visit(AssignmentNode node) { AstNode nodeToChange = vTable.get(node.getIdentifier().toString()); AstNode toChange = node.getValue(); replaceValue(nodeToChange, toChange); -// if (toChange instanceof BinaryOperatorNode) { -// toChange = visit((BinaryOperatorNode) toChange); -// } -// if (toChange instanceof FunctionCallNode) { -// toChange = visit((FunctionCallNode) toChange); -// } -// if (toChange instanceof IdentifierNode) { -// toChange = getVariable((IdentifierNode) toChange); -// } -// if (node.getValue() instanceof RelationsAndLogicalOperatorNode) { -// toChange = visit((RelationsAndLogicalOperatorNode) toChange); -// } -// AstNode finalToChange = toChange; -// switch (nodeToChange) { -// case IntNode intNode when finalToChange instanceof IntNode -> -// intNode.setValue(((IntNode) finalToChange).getValue()); -// case FloatNode floatNode when finalToChange instanceof FloatNode -> -// floatNode.setValue(((FloatNode) finalToChange).getValue()); -// case StringNode stringNode when finalToChange instanceof StringNode -> -// stringNode.setValue(((StringNode) finalToChange).getValue()); -// case BoolNode boolNode when finalToChange instanceof BoolNode -> -// boolNode.setValue(((BoolNode) finalToChange).getValue()); -// case null, default -> throw new RuntimeException("Type mismatch"); -// } return; } } diff --git a/test.carl b/test.carl index b719b9e..2864f06 100644 --- a/test.carl +++ b/test.carl @@ -1,7 +1,11 @@ setSeed(242) -generateMap(20,25) -generateRooms(3,5,7) -generateCorridors() -generateSpawns() -printMap() -writeToFile() \ No newline at end of file +var map : string [20][25] +var i : int = 0 +while(i < 20){ + var j : int = 0 + while(j < 25){ + map[i][j] = "w" + j = j+1 + } + i = i +1 +} From ae5454b4754e827d32565435f0021b0737774aaa Mon Sep 17 00:00:00 2001 From: MShadiF Date: Mon, 29 Apr 2024 15:47:33 +0200 Subject: [PATCH 29/94] Function declaration, functioncall, returnstatement --- .../antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 | 2 +- .../carl/Semantic_A/TypeChecker.java | 211 ++++++++++++------ 2 files changed, 149 insertions(+), 64 deletions(-) diff --git a/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 b/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 index 50f430c..40cf68d 100644 --- a/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 +++ b/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 @@ -123,7 +123,7 @@ coordinateDeclaration : 'var' IDENTIFIER ':' 'coord' '=' '(' expression ',' expr INT : [-]?[0-9]+ ; FLOAT : [-]?[0-9]* '.' [0-9]+ ; STRING : '"' ~["]* '"' ; -BOOL : '\b(true|false)\b' ; +BOOL : ('true' | 'false') ; IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_]* ; WS : [ \t\r\n]+ -> skip ; LINE_COMMENT : '//' ~[\r\n]* -> skip ; diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 3e4afa2..5d1c6d6 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -4,22 +4,30 @@ import java.util.*; -import javax.print.DocFlavor.STRING; - public class TypeChecker { - HashMap fTable; // function table, identifier(x) og node + + HashMap TypeOfReturnFunction; + HashMap > FunctionParameters; + + // HashMap fTable; // function table, identifier(x) og node + HashMap ETable;// variable table, identifier(x) og node(int) Stack> scopes; // scope table, variable identifier(x) og node Deque activeScope;// Hvilket scope vi er i nu - int error =1; - Boolean print_debugger = true; + int errorNumber = 1; + Boolean print_debugger = false; + Boolean has_return_statement = false; + String current_active_function =""; + public TypeChecker() { - fTable = new HashMap<>(); +// fTable = new HashMap<>(); ETable = new HashMap<>(); scopes = new Stack<>(); activeScope = new ArrayDeque<>(); activeScope.push(0); scopes.add(ETable); + TypeOfReturnFunction = new HashMap<>(); + FunctionParameters = new HashMap<>(); } public void visitor(AstNode node) { @@ -52,8 +60,26 @@ public void visitStatements(StatementNode node) { if (node.getNode() instanceof WhileLoopNode) { visitWhileLoop((WhileLoopNode) node.getNode()); } + if (node.getNode() instanceof FunctionDefinitionNode) { + visitFunctionDefinition((FunctionDefinitionNode) node.getNode()); + } + if (node.getNode() instanceof FunctionCallNode){ + visitFunctionCall((FunctionCallNode) node.getNode()); + } + if (node.getNode() instanceof ReturnStatementNode){ + has_return_statement = true; + + System.out.println("we get in return statement"+has_return_statement); + visitReturnNode((ReturnStatementNode) node.getNode()); + + } } + public void error_handler(String errorMessage){ + System.err.println("Error " + errorNumber); + errorNumber = errorNumber + 1; + System.err.println(errorMessage); + } public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { AstNode left = node.getLeft(); @@ -73,10 +99,8 @@ public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { return Type.BOOLEAN; } - System.out.println("Error:"+error); - error = error+1; - System.err.println( - "Wrong types for relation operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); + error_handler("Wrong types for relation operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); + return Type.VOID; } @@ -96,10 +120,7 @@ public Type binaryoperator_type_check(BinaryOperatorNode node) { } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { return Type.FLOAT; } - System.out.println("Error:"+error); - error = error+1; - System.err.println( - "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); + error_handler("Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); return Type.VOID; } @@ -121,7 +142,6 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { Type variableType = getType(node.getType()); // Left side type AstNode ass = node.getValue(); // THis is right side should be a node - System.out.println("Right side on declaration:" + ass.getClass()); Type assignmentType = getType(ass); // This should give right side type if (variableType == assignmentType) { @@ -129,50 +149,60 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { scopes.getLast().put(node.getIdentifier().toString(), Type_we_save_in_E_table); } else { - System.out.println("Error:"+error); - error = error+1; - System.err.println("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier - + " that has the type:" + variableType - + " And that is hella iligal"); + error_handler("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + + " that has the type:" + variableType + + " And that is hella iligal"); + } } else { throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); } } catch (Exception e) { - System.err.println(e.getMessage()); + error_handler(e.getMessage()); } } public Type getVariable(IdentifierNode node) { if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { - System.out.print("Get Varible identifier:" + node.getIdentifier()); - System.out.println(": Get Varible type:" + scopes.getFirst().get(node.getIdentifier().toString())); return scopes.getFirst().get(node.getIdentifier().toString()); } - for (int i = activeScope.getLast(); i < scopes.size(); i++) { if (scopes.get(i).containsKey(node.getIdentifier().toString())) { - System.out.println("Get Varible2" + scopes.getFirst().get(node.getIdentifier().toString())); return scopes.get(i).get(node.getIdentifier().toString()); } } - System.err.println("could not find the variable: " + node.getIdentifier()); throw new RuntimeException("could not find the variable " + node.getIdentifier()); + } + // Check if return = type er det samme som den function den står i. + public void visitReturnNode(ReturnStatementNode node) { + Type returnType = getType(node.getReturnValue()); + Type activeFunction = TypeOfReturnFunction.get(current_active_function); + if(Objects.equals(current_active_function, "")){ + error_handler("You have made return statement outside a function THAT IS illigal"); + } + if(returnType != activeFunction){ + error_handler("The return type " + returnType + " Does not match the return statement of the function " + activeFunction.getTypeName()); + } + if (Objects.equals(returnType.toString(), )) { + error_handler("Missing return statement"); + } } public void visitAssignNode(AssignmentNode node) { if(print_debugger){ - System.out.println("Scopes:"+scopes); - System.out.println("Value"+node.getValue()); + } + boolean found_identifier = false; for (HashMap ETable : scopes) { - if(print_debugger){ - System.out.println("Identifier"+node.getIdentifier().toString()); - System.out.println("Etable:"+ETable); - } - if (ETable.containsKey(node.getIdentifier().toString())) {// hvis x er i scope + + if(true){ + System.out.println("Identifier"+node.getIdentifier().toString()); + System.out.println("Etable:"+ETable); + } + if (ETable.containsKey(node.getIdentifier().toString())) {// hvis x er i scope + found_identifier = true; // tjekke om det er lovligt. // hent gamle type og nye type. Type oldType = getType(node.getIdentifier()); @@ -182,17 +212,18 @@ public void visitAssignNode(AssignmentNode node) { // tjekke om det er lovligt. if (oldType != rightType) { - System.out.println("Error:"+error); - error = error+1; - System.err.println("Tryied to asssign Type:" + rightType + " to the variable:" + identifier - + " that has the type:" + oldType - + " And that is hella iligal"); + error_handler("Tryied to asssign Type:" + rightType + " to the variable:" + identifier + + " that has the type:" + oldType + + " And that is hella iligal"); + } - return; - } + } else { + error_handler("Variable '" + node.getIdentifier() + "' has not been defined yet."); + } + if (found_identifier){ + break; + } } - - throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); } /* @@ -215,7 +246,7 @@ public void visitIfStatement(IfStatementNode node) { } expression = getType(node.getExpressions().get(i).getNode()); if (expression != Type.BOOLEAN) { - System.err.println("If statements expresion must resolve to bool expresion, and this resolve to Type:" + error_handler("If statements expression must resolve to bool expression, and this resolve to Type:" + expression); } } @@ -224,33 +255,91 @@ public void visitIfStatement(IfStatementNode node) { System.out.println("We get in 2 for loop"); System.out.println("Number of blocks:"+node.getBlocks().size()); } - HashMap localTable = new HashMap<>(); - scopes.add(localTable); + HashMap localETable = new HashMap<>(); + scopes.add(localETable); visitBlockNode(node.getBlocks().get(i)); - System.out.println(node.getBlocks().get(i)); - scopes.remove(localTable); + scopes.remove(localETable); } } public void visitWhileLoop(WhileLoopNode node) { Type toCheck = getType((node.getExpression()).getNode()); if (toCheck != Type.BOOLEAN) { - System.err.println( - "While loop expresion must resolve to bool expresion, and this resolve to Type:" + toCheck); + error_handler("While loop expresion must resolve to bool expresion, and this resolve to Type:" + toCheck); + } HashMap localTable = new HashMap<>(); scopes.add(localTable); visitBlockNode(node.getBlock()); - System.out.println(node.getBlock()); + System.out.println(localTable); scopes.remove(localTable); } - public void visitBlockNode(BlockNode node) { - if(true){ - System.out.println("We get in vissitblock for loop"); - System.out.println("Number of statements:"+node.getStatements().size()); + public void visitFunctionDefinition(FunctionDefinitionNode node) { + System.out.println(node+"We get in here"); + if (!TypeOfReturnFunction.containsKey(node.toString()) && !FunctionParameters.containsKey(node.toString())) { + TypeOfReturnFunction.put(node.getIdentifier().toString(), getType(node.getReturnType())); // Key identifier // Type + FunctionParameters.put(node.getIdentifier().toString(), new ArrayList<>()); + + HashMap localTable = new HashMap<>(); + scopes.add(localTable); + List parameters = node.getArguments().getParameters(); + for (ParameterNode parameter : parameters) { + String identifierParameter = String.valueOf((parameter.getIdentifier())); // int carl + Type arguementType = getType(parameter.getType()); + if(localTable.containsKey(identifierParameter) ){ + error_handler("The variable:"+identifierParameter+" Already exist in this function parameters."); + } else { + scopes.getLast().put(identifierParameter, arguementType); + FunctionParameters.get(node.getIdentifier().toString()).add(arguementType);// Den tilføjer typen til listen. Fn x tilføjet int x, int x, int x + } + } + current_active_function = node.getIdentifier().toString(); + has_return_statement = false; + visitBlockNode(node.getBlock());// Alle statement i fn. En af dem er returnStatement + current_active_function = ""; + if(!has_return_statement){ + error_handler("Missing return statement in function declartion:"+node.getIdentifier().toString()); + } + has_return_statement = false; + scopes.remove(localTable); + } else { + error_handler("function " + node.getIdentifier() + " already exists"); } + } + /* + * Vi skal sammenligne argumenterne med paremetrene. + * Vi skal tjekke at der lige mange. + * Der mangler fx argumenter der er ikke nok. eller der for mange. + * Vi skal sige hvis arguemtnet er en forkert type. + * */ + public void visitFunctionCall(FunctionCallNode node) { + if(!Objects.equals(node.getFunctionName().toString(), "print")) { + HashMap localETable = new HashMap<>(); + scopes.add(localETable); + if (TypeOfReturnFunction.containsKey(node.getFunctionName().toString())) { + List expected_Parameter_Types = FunctionParameters.get(node.getFunctionName().toString()); + + int expected_arguments_size = expected_Parameter_Types.size(); + int actual_arguments_size = node.getArguments().size(); + if(expected_arguments_size != actual_arguments_size){ + error_handler("Function Expected:"+expected_arguments_size+" Arguments but got :"+actual_arguments_size+" Arguments"); + } + + for (int i = 0; i < expected_arguments_size; i++) { + if (expected_Parameter_Types.get(i) != getType(node.getArgument(i))) { + error_handler("Function Expected type: " + expected_Parameter_Types.get(i) + ", as "+ i + " Argument but got " + getType(node.getArgument(i))); + } + } + + } else { + error_handler("The function :" + node.getFunctionName().toString() + " May not exist or be out of scope."); + } + } + } + + public void visitBlockNode(BlockNode node) { for (AstNode statement : node.getStatements()) { visitStatements((StatementNode) statement); } @@ -259,8 +348,7 @@ public void visitBlockNode(BlockNode node) { public Type getType(Object node) { Type type = Type.VOID; - if (node instanceof IdentifierNode) { - System.out.println(node.toString()); + if (node instanceof IdentifierNode) { // true bool node. true identifier node if ("true".equals(node.toString()) || "false".equals(node.toString())) { type = Type.BOOLEAN; } else { @@ -271,25 +359,23 @@ public Type getType(Object node) { type = binaryoperator_type_check((BinaryOperatorNode) node); } else if (node instanceof RelationsAndLogicalOperatorNode) { type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) node); + } else if (node instanceof FunctionCallNode){ + String variable_name = ((FunctionCallNode) node).getFunctionName().toString(); + type = TypeOfReturnFunction.get(variable_name); } else if (node instanceof IntNode) { - IntNode intNode = (IntNode) node; - Object value = intNode.getValue(); type = Type.INT; } else if (node instanceof FloatNode) { type = Type.FLOAT; } else if (node instanceof BoolNode) { - System.out.println("Returns Bool type"); type = Type.BOOLEAN; } else if (node instanceof ExpressionNode) { } else if (node instanceof StringNode) { - System.out.println("We get into string node"); type = Type.STRING; } else if (node instanceof TypeNode) { String type_fuck_me_why_did_we_save_types_as_String = ((TypeNode) node).getType(); - System.out.println("A :" + type_fuck_me_why_did_we_save_types_as_String + " :got in Here"); switch (type_fuck_me_why_did_we_save_types_as_String) { case "int": return Type.INT; @@ -304,7 +390,6 @@ else if (node instanceof IntNode) { } if (node instanceof String) { // Directly handling raw Strings - System.out.println("We get the string class raw string" + node); return Type.STRING; } else if (node instanceof Integer) { // Directly handling raw Integers return Type.INT; @@ -315,7 +400,7 @@ else if (node instanceof IntNode) { } } else { - System.err.println("The node we get failed to handle:" + node.getClass()); + error_handler("The node we get failed to handle:" + node.getClass()); } return type; } From 668c1a0f56f2c2716bee9ddd4f701d4ac1ff7dc5 Mon Sep 17 00:00:00 2001 From: MShadiF Date: Mon, 29 Apr 2024 15:50:08 +0200 Subject: [PATCH 30/94] lille update --- .../java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 5d1c6d6..63ee1ad 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -185,9 +185,6 @@ public void visitReturnNode(ReturnStatementNode node) { if(returnType != activeFunction){ error_handler("The return type " + returnType + " Does not match the return statement of the function " + activeFunction.getTypeName()); } - if (Objects.equals(returnType.toString(), )) { - error_handler("Missing return statement"); - } } public void visitAssignNode(AssignmentNode node) { From 7335f45308fdff04a08ce1ff9657adbe0a7fed90 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Mon, 29 Apr 2024 20:39:57 +0200 Subject: [PATCH 31/94] Gav forkert fejl --- .../cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java | 2 +- test.carl | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 63ee1ad..6c24b4e 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -296,7 +296,7 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { has_return_statement = false; visitBlockNode(node.getBlock());// Alle statement i fn. En af dem er returnStatement current_active_function = ""; - if(!has_return_statement){ + if(!has_return_statement && Type.VOID != getType(node.getReturnType())){ error_handler("Missing return statement in function declartion:"+node.getIdentifier().toString()); } has_return_statement = false; diff --git a/test.carl b/test.carl index f028418..4c30525 100644 --- a/test.carl +++ b/test.carl @@ -18,3 +18,14 @@ var expression_true:bool =true if expression_true { sej = nej } + +fn test2 (haha : int, baba : bool) -> void{ + +} + +fn test3 (haha : int, baba : bool) -> int{ + +} + + +test2(69420,true) \ No newline at end of file From 4034e4523c6198d6d5f230bc61481447b0e32b0c Mon Sep 17 00:00:00 2001 From: mantarias Date: Wed, 1 May 2024 10:57:16 +0200 Subject: [PATCH 32/94] removed unnecessary map --- map.json | 49 ------------------------------------------------- 1 file changed, 49 deletions(-) delete mode 100644 map.json diff --git a/map.json b/map.json deleted file mode 100644 index 081d291..0000000 --- a/map.json +++ /dev/null @@ -1,49 +0,0 @@ -{"map" : { - "size":{ - "height" : 10, - "width" : 10 - }, - "tiles": [ - -{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","f","f","f","f","f","f","w","w","w","w","w","w","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","f","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","f","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","f","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","f","f","f","f","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","w","w","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","w","w","w","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","p","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","f","f","f","f","f","w","w","w","w","w"]}, -{"row":["w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w","w"]}], -"level" : 1, -"type" : "Room", -"tileInformation":[ -{ -"symbol" : "w" , -"info" : { - "name" : "Wall" - } -}, -{ -"symbol" : "f" , -"info" : { - "name" : "Floor" - } -}, -{ -"symbol" : "p" , -"info" : { - "name" : "Player" - } -} -]}} \ No newline at end of file From db0c278a1ba1a8b4b3228c383a83cf53063b66ed Mon Sep 17 00:00:00 2001 From: Vincent Kosteyev Bechmann Date: Wed, 1 May 2024 22:06:01 +0200 Subject: [PATCH 33/94] I think I got things to work and things compile and I hope that nothing bad will result from this pleas e p;easeseeee --- .../antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 | 6 +- .../carl/CstToAst/ArrayAccessNode.java | 4 +- .../carl/CstToAst/ArrayAssignmentNode.java | 4 +- .../carl/CstToAst/ArrayDefinitionNode.java | 10 +--- .../carl/CstToAst/CstToAstVisitor.java | 15 ++++- .../carl/Interpreter/Interpreter.java | 56 ++++++++++++++++--- 6 files changed, 71 insertions(+), 24 deletions(-) diff --git a/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 b/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 index 40cf68d..e4c4d2c 100644 --- a/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 +++ b/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 @@ -28,7 +28,7 @@ variableDeclaration : 'var' IDENTIFIER ':' type '=' (expression) ; arrayDeclaration : 'var' IDENTIFIER ':' legalArrayType arrayOptionalIndex+; -arrayOptionalIndex : '[' INT? ']' ; +arrayOptionalIndex : '[' expression? ']' ; legalArrayType : 'bool' @@ -55,7 +55,7 @@ type : | 'void' | 'string' | IDENTIFIER - | legalArrayType '[' INT? ']' ('[' INT? ']')* + | legalArrayType '[' expression? ']' ('[' expression? ']')* ; assignment : (IDENTIFIER | arrayAccess) '=' expression ; propertyAssignment : propertyAccess '=' expression ; @@ -115,7 +115,7 @@ ifStatement : 'if' expression block ( 'else if' expression block )* ( 'else' blo whileLoop : 'while' expression block ; returnStatement : 'return' expression? ; block : '{' (statement | expression)* '}' ; -arrayAccess : IDENTIFIER '[' INT ']' ('[' INT ']')*; +arrayAccess : IDENTIFIER '[' expression ']' ('[' expression ']')*; propertyAccess : structType '.' IDENTIFIER ('.' IDENTIFIER)? ; coordinateDeclaration : 'var' IDENTIFIER ':' 'coord' '=' '(' expression ',' expression ')' ;//Virker ikke nødvendigt, hvorfor ikke bare bruge arrayAcces? diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayAccessNode.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayAccessNode.java index 6c24290..f46fe58 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayAccessNode.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayAccessNode.java @@ -6,11 +6,11 @@ @Getter public class ArrayAccessNode extends AstNode { - final private List indices; + final private List indices; final private IdentifierNode identifier; - public ArrayAccessNode(IdentifierNode identifier, List indices){ + public ArrayAccessNode(IdentifierNode identifier, List indices){ this.identifier = identifier; this.indices = indices; } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayAssignmentNode.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayAssignmentNode.java index e5e9a3c..6b22f70 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayAssignmentNode.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayAssignmentNode.java @@ -8,10 +8,10 @@ public class ArrayAssignmentNode extends AstNode { final private IdentifierNode identifier; - final private List indices; + final private List indices; final private AstNode value; - public ArrayAssignmentNode(IdentifierNode identifier, List indices, ExpressionNode value){ + public ArrayAssignmentNode(IdentifierNode identifier, List indices, ExpressionNode value){ this.identifier = identifier; this.indices = indices; this.value = value; diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayDefinitionNode.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayDefinitionNode.java index 035ca71..d2f167a 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayDefinitionNode.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayDefinitionNode.java @@ -8,17 +8,13 @@ public class ArrayDefinitionNode extends AstNode { @Getter private final TypeNode type; // we need this only if dynamic sizing is allowed - @Getter private final List sizes; + @Getter private final List sizes; - private IdentifierNode identifier; + @Getter private final IdentifierNode identifier; - public ArrayDefinitionNode(TypeNode type, List sizes, IdentifierNode identifier) { + public ArrayDefinitionNode(TypeNode type, List sizes, IdentifierNode identifier) { this.type = type; this.sizes = sizes; this.identifier = identifier; } - - public String getIdentifier() { - return identifier.toString(); - } } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java index 8b74f83..32e231c 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java @@ -89,13 +89,22 @@ public AstNode visitArrayDeclaration(CARLParser.ArrayDeclarationContext ctx) { TypeNode type = (TypeNode) /*This is the part where we pray to God that it does indeed return a TypeNode */ visit(ctx.legalArrayType()); - List sizes = ctx.arrayOptionalIndex().stream() + /*List sizes = ctx.arrayOptionalIndex().stream() .map(arrayOptionalIndexContext -> { if (arrayOptionalIndexContext.INT() == null) return -1; else return Integer.parseInt(arrayOptionalIndexContext.INT().getText()); //And on this line, we pray that the int is indeed an int... }) + .toList();*/ + + List sizes = ctx.arrayOptionalIndex().stream() + .map(arrayOptionalIndexContext -> { + if(arrayOptionalIndexContext.expression() == null) + return new IntNode(-1); + else + return new ExpressionNode(visit(arrayOptionalIndexContext.expression())); + }) .toList(); return new ArrayDefinitionNode(type, sizes, identifierNode); @@ -130,7 +139,9 @@ else if (ctx.arrayAccess() != null) public AstNode visitArrayAccess(CARLParser.ArrayAccessContext ctx) { IdentifierNode id = new IdentifierNode(ctx.IDENTIFIER().getText()); - List indices = ctx.INT().stream().map(tn -> Integer.parseInt(tn.getText())).toList(); + //List indices = ctx.INT().stream().map(tn -> Integer.parseInt(tn.getText())).toList(); + + List indices = ctx.expression().stream().map(e -> new ExpressionNode(visit(e)).getNode()).toList(); return new ArrayAccessNode(id, indices); } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java index 5052bc1..43f5585 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java @@ -3,6 +3,7 @@ import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; import java.util.*; +import java.util.stream.IntStream; public class Interpreter { HashMap fTable; @@ -296,19 +297,28 @@ public void visit(VariableDeclarationNode node) { } - //I hate Java for forcing me to make this function - //It is as stupid as its name makes it sound - private int[] integerListToIntArray(List ints) { - return Arrays.stream(ints.toArray(new Integer[0])).mapToInt(i -> i).toArray(); + private int[] astNodeListToIntArray(List ints) { + return Arrays.stream(ints.toArray(new AstNode[0])).mapToInt(i -> evaluate_int(i).getValue()).toArray(); } public AstNode visit(ArrayAccessNode node) { - return ((ArrayNode) getVariable(node.getIdentifier())).get(integerListToIntArray(node.getIndices())); + //Explanation: + // 1. Get the ArrayNode behind the identifier. + // 2. Convert the List into int[] (through evaluate_int()) + // 3. ??? + // 4. Profit + + return ((ArrayNode) getVariable(node.getIdentifier())) + .get( + node.getIndices().stream().mapToInt( + astNode -> evaluate_int(astNode).getValue() + ).toArray() + ); } public void visit(ArrayAssignmentNode node) { - int[] indices = integerListToIntArray(node.getIndices()); + int[] indices = astNodeListToIntArray(node.getIndices()); AstNode value; @@ -331,12 +341,42 @@ public void visit(ArrayAssignmentNode node) { ((ArrayNode) getVariable(node.getIdentifier())).set(value, indices); } + private IntNode evaluate_int(AstNode node){ + if (node instanceof BinaryOperatorNode) { + return (IntNode) visit((BinaryOperatorNode) node); + } else if (node instanceof IdentifierNode) { + + var value = getVariable((IdentifierNode) node); + if (value instanceof IntNode ) + return (IntNode) value; + else + throw new RuntimeException("Type mismatch: Expected " + ((IdentifierNode) node).getIdentifier() + " to be an int, got " + value.getClass()); + } else if (node instanceof FunctionCallNode){ + var value = visit((FunctionCallNode) node); + if (value instanceof IntNode ) + return (IntNode) value; + else + throw new RuntimeException("Type mismatch: Expected " + ((FunctionCallNode) node).getFunctionName().getIdentifier() + "() to return an int, got " + value.getClass()); + } else if (node instanceof RelationsAndLogicalOperatorNode){ + var value = visit((RelationsAndLogicalOperatorNode) node); + if (value instanceof IntNode ) + return (IntNode) value; + else + throw new RuntimeException("Type mismatch: " + ((RelationsAndLogicalOperatorNode) node).operator + " operator doesn't return an int"); + } else if (node instanceof IntNode) { + return (IntNode) node; + } else { + throw new RuntimeException("Expected an integer, got " + node.getClass()); + } + } + public void visit(ArrayDefinitionNode node) { - if (idExists(node.getIdentifier())) { + if (idExists(node.getIdentifier().getIdentifier())) { throw new RuntimeException("Variable '" + node.getIdentifier() + "' already exists."); } - scopes.getLast().put(node.getIdentifier(), new ArrayNode(node.getType(), new ArrayList<>(node.getSizes()))); + scopes.getLast() + .put(node.getIdentifier().getIdentifier(), new ArrayNode(node.getType(), new ArrayList<>(node.getSizes().stream().mapToInt(n -> evaluate_int(n).getValue()).boxed().toList()))); } private boolean idExists(String id) { From 4ee2b1a4d8fdd3f864cc88eda2d5472863396bd3 Mon Sep 17 00:00:00 2001 From: Vincent Kosteyev Bechmann Date: Thu, 18 Apr 2024 11:43:43 +0200 Subject: [PATCH 34/94] Fixed up pom, I think --- pom.xml | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/pom.xml b/pom.xml index 1b2381b..004912c 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,7 @@ + org.projectlombok lombok @@ -25,21 +26,12 @@ provided - - - junit - junit - 4.13.2 - - - - + org.antlr antlr4-runtime 4.13.1 - org.antlr antlr4 @@ -47,6 +39,7 @@ provided + org.junit.jupiter junit-jupiter @@ -57,29 +50,46 @@ + - maven-jar-plugin + org.apache.maven.plugins + maven-assembly-plugin 3.3.0 + + + + package + + single + + + + + jar-with-dependencies + - - ${project.groupId}.Main + + ${project.groupId}.Main + false + + org.antlr antlr4-maven-plugin 4.13.1 - true + true antlr - antlr4 + antlr4 From 02cc0a0d862fb3ec9720a5af1b48621e9b43cece Mon Sep 17 00:00:00 2001 From: Vince Date: Thu, 25 Apr 2024 23:07:49 +0200 Subject: [PATCH 35/94] Fixed the fix --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 004912c..4bdde2e 100644 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,12 @@ 5.9.1 test + + junit + junit + 4.13.2 + + From e57eb5433a673770ab6462065593355714967238 Mon Sep 17 00:00:00 2001 From: Vincent Kosteyev Bechmann Date: Wed, 1 May 2024 23:44:28 +0200 Subject: [PATCH 36/94] Fixed integer evaluator --- .../java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java index 43f5585..726930b 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java @@ -365,6 +365,8 @@ private IntNode evaluate_int(AstNode node){ throw new RuntimeException("Type mismatch: " + ((RelationsAndLogicalOperatorNode) node).operator + " operator doesn't return an int"); } else if (node instanceof IntNode) { return (IntNode) node; + } else if (node instanceof ExpressionNode){ + return evaluate_int(((ExpressionNode) node).getNode()); } else { throw new RuntimeException("Expected an integer, got " + node.getClass()); } From 7aad75ff84e3ae0c18a15bd0631624a5e05afc0f Mon Sep 17 00:00:00 2001 From: Vincent Kosteyev Bechmann Date: Thu, 2 May 2024 08:33:54 +0200 Subject: [PATCH 37/94] Fixed how minus works --- src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 | 11 +++++++---- .../cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java | 10 ++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 b/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 index e4c4d2c..2dd157f 100644 --- a/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 +++ b/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 @@ -76,8 +76,8 @@ expression ; primary - : INT # Int - | FLOAT # Float + : integer # Int + | fpNum # Float | STRING # String | IDENTIFIER # Identifier | BOOL # Bool @@ -119,9 +119,12 @@ arrayAccess : IDENTIFIER '[' expression ']' ('[' expression ']')*; propertyAccess : structType '.' IDENTIFIER ('.' IDENTIFIER)? ; coordinateDeclaration : 'var' IDENTIFIER ':' 'coord' '=' '(' expression ',' expression ')' ;//Virker ikke nødvendigt, hvorfor ikke bare bruge arrayAcces? +integer : '-'? INT; +fpNum : '-'? FLOAT; + // Lexer rules -INT : [-]?[0-9]+ ; -FLOAT : [-]?[0-9]* '.' [0-9]+ ; +INT : [0-9]+ ; +FLOAT : [0-9]* '.' [0-9]+ ; STRING : '"' ~["]* '"' ; BOOL : ('true' | 'false') ; IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_]* ; diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java index 32e231c..2942465 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java @@ -202,6 +202,11 @@ public AstNode visitInt(CARLParser.IntContext ctx) { return new IntNode(ctx.getText()); } + @Override + public AstNode visitInteger(CARLParser.IntegerContext ctx) { + return new IntNode(ctx.getText()); + } + @Override public AstNode visitDummyFunctionCallExpr(CARLParser.DummyFunctionCallExprContext ctx) { return super.visitDummyFunctionCallExpr(ctx); @@ -301,6 +306,11 @@ public AstNode visitFloat(CARLParser.FloatContext ctx) { return new FloatNode(ctx.getText()); } + @Override + public AstNode visitFpNum(CARLParser.FpNumContext ctx) { + return new FloatNode(ctx.getText()); + } + @Override public AstNode visitNot(CARLParser.NotContext ctx) { AstNode left = visit(ctx.expression()); //Why do we need both a left and a right if they're the same? -Vincent From 13435cdb045ebe58f58d4777a684fb752403ef4c Mon Sep 17 00:00:00 2001 From: Vincent Kosteyev Bechmann Date: Thu, 2 May 2024 10:43:56 +0200 Subject: [PATCH 38/94] Consistent-icised case system Converted Carl's combination of PascalCase, camelCase, snake_case, and Snake_Pascal_Case into a more consistent system. Also, removed swear words. --- .../carl/Semantic_A/TypeChecker.java | 158 +++++++++--------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 6c24b4e..c669971 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -6,28 +6,28 @@ public class TypeChecker { - HashMap TypeOfReturnFunction; - HashMap > FunctionParameters; + HashMap typeOfReturnFunction; + HashMap > functionParameters; // HashMap fTable; // function table, identifier(x) og node - HashMap ETable;// variable table, identifier(x) og node(int) + HashMap eTable;// variable table, identifier(x) og node(int) Stack> scopes; // scope table, variable identifier(x) og node Deque activeScope;// Hvilket scope vi er i nu int errorNumber = 1; - Boolean print_debugger = false; - Boolean has_return_statement = false; - String current_active_function =""; + Boolean printDebugger = false; + Boolean hasReturnStatement = false; + String currentActiveFunction =""; public TypeChecker() { // fTable = new HashMap<>(); - ETable = new HashMap<>(); + eTable = new HashMap<>(); scopes = new Stack<>(); activeScope = new ArrayDeque<>(); activeScope.push(0); - scopes.add(ETable); - TypeOfReturnFunction = new HashMap<>(); - FunctionParameters = new HashMap<>(); + scopes.add(eTable); + typeOfReturnFunction = new HashMap<>(); + functionParameters = new HashMap<>(); } public void visitor(AstNode node) { @@ -43,7 +43,7 @@ public void visitProgramNode(ProgramNode node) { } public void visitStatements(StatementNode node) { - if(print_debugger){ + if(printDebugger){ System.out.println("We get in the vist statement"); System.out.println(node.getClass()); System.out.println(node.getNode().getClass()); @@ -67,60 +67,60 @@ public void visitStatements(StatementNode node) { visitFunctionCall((FunctionCallNode) node.getNode()); } if (node.getNode() instanceof ReturnStatementNode){ - has_return_statement = true; + hasReturnStatement = true; - System.out.println("we get in return statement"+has_return_statement); + System.out.println("we get in return statement"+ hasReturnStatement); visitReturnNode((ReturnStatementNode) node.getNode()); } } - public void error_handler(String errorMessage){ + public void errorHandler(String errorMessage){ System.err.println("Error " + errorNumber); errorNumber = errorNumber + 1; System.err.println(errorMessage); } - public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { + public Type relationOperatorTypeCheck(RelationsAndLogicalOperatorNode node) { AstNode left = node.getLeft(); AstNode right = node.getRight(); - Type left_type = Type.VOID; - Type right_Type = Type.VOID; + Type leftType = Type.VOID; + Type rightType = Type.VOID; - left_type = getType(left); - right_Type = getType(right); + leftType = getType(left); + rightType = getType(right); - if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. + if (leftType == Type.INT && rightType == Type.INT) { // Her at udregning sker, som ikke burde ske. return Type.BOOLEAN; - } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { + } else if (leftType == Type.FLOAT && rightType == Type.FLOAT) { return Type.BOOLEAN; - } else if (left_type == Type.BOOLEAN && right_Type == Type.BOOLEAN) { + } else if (leftType == Type.BOOLEAN && rightType == Type.BOOLEAN) { return Type.BOOLEAN; } - error_handler("Wrong types for relation operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); + errorHandler("Wrong types for relation operation:" + leftType + ":" + left + " And:" + right + ":" + rightType); return Type.VOID; } - public Type binaryoperator_type_check(BinaryOperatorNode node) { + public Type binaryOperatorTypeCheck(BinaryOperatorNode node) { AstNode left = node.getLeft(); // Får venstre x som i result=x+y i node form AstNode right = node.getRight();// Får højre y i node form - Type left_type = Type.VOID; - Type right_Type = Type.VOID; + Type leftType = Type.VOID; + Type rightType = Type.VOID; - left_type = getType(left); - right_Type = getType(right); + leftType = getType(left); + rightType = getType(right); - if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. + if (leftType == Type.INT && rightType == Type.INT) { // Her at udregning sker, som ikke burde ske. return Type.INT; - } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { + } else if (leftType == Type.FLOAT && rightType == Type.FLOAT) { return Type.FLOAT; } - error_handler("Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); + errorHandler("Wrong types for binary operation:" + leftType + ":" + left + " And:" + right + ":" + rightType); return Type.VOID; } @@ -145,11 +145,11 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { Type assignmentType = getType(ass); // This should give right side type if (variableType == assignmentType) { - Type Type_we_save_in_E_table = variableType; - scopes.getLast().put(node.getIdentifier().toString(), Type_we_save_in_E_table); + Type typeWeSaveInETable = variableType; + scopes.getLast().put(node.getIdentifier().toString(), typeWeSaveInETable); } else { - error_handler("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + errorHandler("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + " that has the type:" + variableType + " And that is hella iligal"); @@ -158,7 +158,7 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); } } catch (Exception e) { - error_handler(e.getMessage()); + errorHandler(e.getMessage()); } } @@ -178,20 +178,20 @@ public Type getVariable(IdentifierNode node) { // Check if return = type er det samme som den function den står i. public void visitReturnNode(ReturnStatementNode node) { Type returnType = getType(node.getReturnValue()); - Type activeFunction = TypeOfReturnFunction.get(current_active_function); - if(Objects.equals(current_active_function, "")){ - error_handler("You have made return statement outside a function THAT IS illigal"); + Type activeFunction = typeOfReturnFunction.get(currentActiveFunction); + if(Objects.equals(currentActiveFunction, "")){ + errorHandler("You have made return statement outside a function THAT IS illigal"); } if(returnType != activeFunction){ - error_handler("The return type " + returnType + " Does not match the return statement of the function " + activeFunction.getTypeName()); + errorHandler("The return type " + returnType + " Does not match the return statement of the function " + activeFunction.getTypeName()); } } public void visitAssignNode(AssignmentNode node) { - if(print_debugger){ + if(printDebugger){ } - boolean found_identifier = false; + boolean foundIdentifier = false; for (HashMap ETable : scopes) { if(true){ @@ -199,7 +199,7 @@ public void visitAssignNode(AssignmentNode node) { System.out.println("Etable:"+ETable); } if (ETable.containsKey(node.getIdentifier().toString())) {// hvis x er i scope - found_identifier = true; + foundIdentifier = true; // tjekke om det er lovligt. // hent gamle type og nye type. Type oldType = getType(node.getIdentifier()); @@ -209,15 +209,15 @@ public void visitAssignNode(AssignmentNode node) { // tjekke om det er lovligt. if (oldType != rightType) { - error_handler("Tryied to asssign Type:" + rightType + " to the variable:" + identifier + errorHandler("Tryied to asssign Type:" + rightType + " to the variable:" + identifier + " that has the type:" + oldType + " And that is hella iligal"); } } else { - error_handler("Variable '" + node.getIdentifier() + "' has not been defined yet."); + errorHandler("Variable '" + node.getIdentifier() + "' has not been defined yet."); } - if (found_identifier){ + if (foundIdentifier){ break; } } @@ -231,24 +231,24 @@ public void visitAssignNode(AssignmentNode node) { public void visitIfStatement(IfStatementNode node) { Type expression = Type.VOID; - if(print_debugger){ + if(printDebugger){ System.out.println("We get in the If statement"); } for (int i = 0; i < node.getExpressions().size(); i++) { - if(print_debugger){ + if(printDebugger){ System.out.println("We get in first for loop"); System.out.println("Number of expressions:"+node.getExpressions().size()); } expression = getType(node.getExpressions().get(i).getNode()); if (expression != Type.BOOLEAN) { - error_handler("If statements expression must resolve to bool expression, and this resolve to Type:" + errorHandler("If statements expression must resolve to bool expression, and this resolve to Type:" + expression); } } for (int i = 0; i < node.getBlocks().size(); i++) { - if(print_debugger){ + if(printDebugger){ System.out.println("We get in 2 for loop"); System.out.println("Number of blocks:"+node.getBlocks().size()); } @@ -263,7 +263,7 @@ public void visitIfStatement(IfStatementNode node) { public void visitWhileLoop(WhileLoopNode node) { Type toCheck = getType((node.getExpression()).getNode()); if (toCheck != Type.BOOLEAN) { - error_handler("While loop expresion must resolve to bool expresion, and this resolve to Type:" + toCheck); + errorHandler("While loop expresion must resolve to bool expresion, and this resolve to Type:" + toCheck); } HashMap localTable = new HashMap<>(); @@ -275,9 +275,9 @@ public void visitWhileLoop(WhileLoopNode node) { public void visitFunctionDefinition(FunctionDefinitionNode node) { System.out.println(node+"We get in here"); - if (!TypeOfReturnFunction.containsKey(node.toString()) && !FunctionParameters.containsKey(node.toString())) { - TypeOfReturnFunction.put(node.getIdentifier().toString(), getType(node.getReturnType())); // Key identifier // Type - FunctionParameters.put(node.getIdentifier().toString(), new ArrayList<>()); + if (!typeOfReturnFunction.containsKey(node.toString()) && !functionParameters.containsKey(node.toString())) { + typeOfReturnFunction.put(node.getIdentifier().toString(), getType(node.getReturnType())); // Key identifier // Type + functionParameters.put(node.getIdentifier().toString(), new ArrayList<>()); HashMap localTable = new HashMap<>(); scopes.add(localTable); @@ -286,23 +286,23 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { String identifierParameter = String.valueOf((parameter.getIdentifier())); // int carl Type arguementType = getType(parameter.getType()); if(localTable.containsKey(identifierParameter) ){ - error_handler("The variable:"+identifierParameter+" Already exist in this function parameters."); + errorHandler("The variable:"+identifierParameter+" Already exist in this function parameters."); } else { scopes.getLast().put(identifierParameter, arguementType); - FunctionParameters.get(node.getIdentifier().toString()).add(arguementType);// Den tilføjer typen til listen. Fn x tilføjet int x, int x, int x + functionParameters.get(node.getIdentifier().toString()).add(arguementType);// Den tilføjer typen til listen. Fn x tilføjet int x, int x, int x } } - current_active_function = node.getIdentifier().toString(); - has_return_statement = false; + currentActiveFunction = node.getIdentifier().toString(); + hasReturnStatement = false; visitBlockNode(node.getBlock());// Alle statement i fn. En af dem er returnStatement - current_active_function = ""; - if(!has_return_statement && Type.VOID != getType(node.getReturnType())){ - error_handler("Missing return statement in function declartion:"+node.getIdentifier().toString()); + currentActiveFunction = ""; + if(!hasReturnStatement && Type.VOID != getType(node.getReturnType())){ + errorHandler("Missing return statement in function declartion:"+node.getIdentifier().toString()); } - has_return_statement = false; + hasReturnStatement = false; scopes.remove(localTable); } else { - error_handler("function " + node.getIdentifier() + " already exists"); + errorHandler("function " + node.getIdentifier() + " already exists"); } } /* @@ -315,23 +315,23 @@ public void visitFunctionCall(FunctionCallNode node) { if(!Objects.equals(node.getFunctionName().toString(), "print")) { HashMap localETable = new HashMap<>(); scopes.add(localETable); - if (TypeOfReturnFunction.containsKey(node.getFunctionName().toString())) { - List expected_Parameter_Types = FunctionParameters.get(node.getFunctionName().toString()); + if (typeOfReturnFunction.containsKey(node.getFunctionName().toString())) { + List expectedParameterTypes = functionParameters.get(node.getFunctionName().toString()); - int expected_arguments_size = expected_Parameter_Types.size(); - int actual_arguments_size = node.getArguments().size(); - if(expected_arguments_size != actual_arguments_size){ - error_handler("Function Expected:"+expected_arguments_size+" Arguments but got :"+actual_arguments_size+" Arguments"); + int expectedArgumentsSize = expectedParameterTypes.size(); + int actualArgumentsSize = node.getArguments().size(); + if(expectedArgumentsSize != actualArgumentsSize){ + errorHandler("Function Expected:"+expectedArgumentsSize+" Arguments but got :"+actualArgumentsSize+" Arguments"); } - for (int i = 0; i < expected_arguments_size; i++) { - if (expected_Parameter_Types.get(i) != getType(node.getArgument(i))) { - error_handler("Function Expected type: " + expected_Parameter_Types.get(i) + ", as "+ i + " Argument but got " + getType(node.getArgument(i))); + for (int i = 0; i < expectedArgumentsSize; i++) { + if (expectedParameterTypes.get(i) != getType(node.getArgument(i))) { + errorHandler("Function Expected type: " + expectedParameterTypes.get(i) + ", as "+ i + " Argument but got " + getType(node.getArgument(i))); } } } else { - error_handler("The function :" + node.getFunctionName().toString() + " May not exist or be out of scope."); + errorHandler("The function :" + node.getFunctionName().toString() + " May not exist or be out of scope."); } } } @@ -353,12 +353,12 @@ public Type getType(Object node) { } } else if (node instanceof BinaryOperatorNode) { - type = binaryoperator_type_check((BinaryOperatorNode) node); + type = binaryOperatorTypeCheck((BinaryOperatorNode) node); } else if (node instanceof RelationsAndLogicalOperatorNode) { - type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) node); + type = relationOperatorTypeCheck((RelationsAndLogicalOperatorNode) node); } else if (node instanceof FunctionCallNode){ - String variable_name = ((FunctionCallNode) node).getFunctionName().toString(); - type = TypeOfReturnFunction.get(variable_name); + String variableName = ((FunctionCallNode) node).getFunctionName().toString(); + type = typeOfReturnFunction.get(variableName); } else if (node instanceof IntNode) { @@ -372,8 +372,8 @@ else if (node instanceof IntNode) { } else if (node instanceof StringNode) { type = Type.STRING; } else if (node instanceof TypeNode) { - String type_fuck_me_why_did_we_save_types_as_String = ((TypeNode) node).getType(); - switch (type_fuck_me_why_did_we_save_types_as_String) { + String typeAsString = ((TypeNode) node).getType(); + switch (typeAsString) { case "int": return Type.INT; case "string": @@ -397,7 +397,7 @@ else if (node instanceof IntNode) { } } else { - error_handler("The node we get failed to handle:" + node.getClass()); + errorHandler("The node we get failed to handle:" + node.getClass()); } return type; } From 7f25b4930b830e3ffed5a05401c81cc6b36825f3 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Fri, 3 May 2024 12:05:50 +0200 Subject: [PATCH 39/94] We are going ham --- .../java/dk/aau/cs_24_sw_4_16/carl/Main.java | 14 +- .../carl/Semantic_A/SemanticAnalyzer.java | 217 ------------------ .../cs_24_sw_4_16/carl/Semantic_A/Type.java | 6 + .../carl/Semantic_A/TypeChecker.java | 214 ++++++++++------- test.carl | 23 -- 5 files changed, 142 insertions(+), 332 deletions(-) delete mode 100644 src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index e385dac..eb3a445 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -3,12 +3,10 @@ import dk.aau.cs_24_sw_4_16.carl.CstToAst.AstNode; import dk.aau.cs_24_sw_4_16.carl.CstToAst.CstToAstVisitor; import dk.aau.cs_24_sw_4_16.carl.Interpreter.Interpreter; -import lombok.Getter; -import lombok.Setter; +import dk.aau.cs_24_sw_4_16.carl.Semantic_A.TypeChecker; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; -import dk.aau.cs_24_sw_4_16.carl.Semantic_A.SemanticAnalyzer; import java.io.FileInputStream; import java.io.IOException; @@ -37,21 +35,19 @@ public static void main(String... args) { // It returns a parse tree representing the entire input file. ParseTree tree = parser.program();// Her stopper det som Antler har lavet. - // CstToAstVisitor is a visitor class that converts the parse tree (CST) into an abstract syntax tree (AST). // This is typically used to simplify and optimize the tree structure for further processing. CstToAstVisitor visitor = new CstToAstVisitor(); // The visit method walks the parse tree and constructs the AST AstNode astRoot = visitor.visit(tree); - //System.out.println(astRoot); System.out.println(astRoot); - - SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer(); - semanticAnalyzer.analyze(astRoot); + + TypeChecker typeChecker = new TypeChecker(); + typeChecker.visitor(astRoot); // Interpreter is a class that can traverse the AST and interpret or execute the program based on the AST. Interpreter inter = new Interpreter(); - + inter.visit(astRoot); } catch (IOException e) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java deleted file mode 100644 index bb65d4c..0000000 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticAnalyzer.java +++ /dev/null @@ -1,217 +0,0 @@ -package dk.aau.cs_24_sw_4_16.carl.Semantic_A; - -import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; -public class SemanticAnalyzer { - - public boolean printTest = false; - - public void analyze(AstNode root) throws SemanticException { - if (printTest) { - // System.out.println("Hej jeg kommer her ind"); - } - // System.out.println("Her starter visitor class"); - - TypeChecker typeChecker = new TypeChecker(); - typeChecker.visitor(root); -System.out.println("-----------------------------------------------"); - System.out.println("Her stopper visitor class"); - - if (root != null) { - visit(root); - } - } - - - private void visit(AstNode node) throws SemanticException { - if (node instanceof ProgramNode) { - visitProgram((ProgramNode) node); - if (printTest) { - System.out.println("Hej jeg kommer ind i programnode"); - } - } else if (node instanceof BinaryOperatorNode) { - visitBinaryOperator((BinaryOperatorNode) node); - if (printTest) { - System.out.println("Hej jeg kommer ind i binary"); - } - } else if (node instanceof StatementNode) { - visitStatement((StatementNode) node); - if (printTest) { - System.out.println("Hej jeg kommer ind i statement"); - } - } else if (node instanceof ExpressionNode) { - visitExpression((ExpressionNode) node); - if (printTest) { - System.out.println("Hej jeg kommer ind i expression"); - } - } else if (node instanceof BlockNode) { - visitBlock((BlockNode) node); - if (printTest) { - System.out.println("Hej jeg kommer ind i block"); - } - } else if (node instanceof IfStatementNode) { - visitIfStatement((IfStatementNode) node); - if (printTest) { - System.out.println("Hej jeg kommer ind i if statement"); - } - } else if (node instanceof WhileLoopNode) { - visitWhileLoop((WhileLoopNode) node); - if (printTest) { - System.out.println("Hej jeg kommer ind i while loop"); - } - } else if (node instanceof FunctionDefinitionNode) { - visitFunctionDefinition((FunctionDefinitionNode) node); - if (printTest) { - System.out.println("Hej jeg kommer ind i function definition"); - } - } else if (node instanceof ReturnStatementNode) { - visitReturnStatement((ReturnStatementNode) node); - if (printTest) { - System.out.println("Hej jeg kommer ind i return statement"); - } - } else if (node instanceof FunctionCallNode) { - visitFunctionCall((FunctionCallNode) node); - if (printTest) { - System.out.println("Hej jeg kommer ind i function call"); - } - } else if (node instanceof VariableDeclarationNode) { - visitVariableDeclaration((VariableDeclarationNode) node); - if (printTest) { - System.out.println("Hej jeg kommer ind i variabledeclaration"); - } - } - - // Add more as necessary - } - - private void visitVariableDeclaration(VariableDeclarationNode node) throws SemanticException { - System.out.println(node.toString()); - visit(node.getValue()); - } - - private void visitProgram(ProgramNode node) throws SemanticException { - for (AstNode statement : node.getStatements()) { - visit(statement); - } - } - - private void visitStatement(StatementNode node) throws SemanticException { - // Assuming StatementNode holds a single statement or compound statements - visit(node.getNode()); - } - - private void visitIfStatement(IfStatementNode node) throws SemanticException { - // visit(node.getCondition()); - // visit(node.getThenBlock()); - // if (node.getElseBlock() != null) { - // visit(node.getElseBlock()); - // } - } - - private void visitWhileLoop(WhileLoopNode node) throws SemanticException { - // visit(node.getCondition()); - // visit(node.getBody()); - } - - private void visitFunctionDefinition(FunctionDefinitionNode node) throws SemanticException { - // for (ParameterNode param : node.getParameters()) { - // visit(param); - // } - // visit(node.getBody()); - } - - private void visitReturnStatement(ReturnStatementNode node) throws SemanticException { - // if (node.getExpression() != null) { - // visit(node.getExpression()); - // } - } - - private void visitFunctionCall(FunctionCallNode node) throws SemanticException { - // for (ExpressionNode argument : node.getArguments()) { - // visit(argument); - // } - } - - private void visitExpression(ExpressionNode node) throws SemanticException { - // Assuming ExpressionNode wraps an expression - visit(node.getNode()); - } - - private void visitBlock(BlockNode node) throws SemanticException { - for (AstNode statement : node.getStatements()) { - visit(statement); - } - } - - private void visitBinaryOperator(BinaryOperatorNode node) throws SemanticException { - // Specific checks for BinaryOperatorNode - checkBinaryExpression(node); - if (printTest) { - System.out.println("Hej jeg kommer int i visitbinary opertor"); - } - // Recursively visit left and right children - visit(node.getLeft()); - visit(node.getRight()); - } - - private void checkBinaryExpression(BinaryOperatorNode node) throws SemanticException { - AstNode left = node.getLeft(); - AstNode right = node.getRight(); - - // Retrieve the types of the left and right operands - Type leftType = getType(left); - Type rightType = getType(right); - try { - // Perform type compatibility check for the specific binary operation - if (!isOperationTypeCompatible(leftType, rightType, node.getOperator())) { - throw new SemanticException( - "Type mismatch for operator '" + node.getOperator() + "': " + leftType + " and " + rightType); - } - } catch (Exception e) { - // TODO: handle exception - } - - // If necessary, set the type for the binary expression itself - // e.g., node.setType(resultingTypeOfOperation(leftType, rightType)); - } - - // Check if the operation is compatible with the given types - private boolean isOperationTypeCompatible(Type leftType, Type rightType, String operator) { - // Example for addition operation - if (operator.equals("+")) { - // Let's assume for simplicity that we can only add numbers - if (leftType == Type.INT && rightType == Type.INT) { - return true; - } - // Add more rules as per your language specification - } - // Include checks for other operators - - return false; // Default to false if not compatible - } - - // Retrieve the type of a given AST node - private Type getType(AstNode node) { - if (node instanceof IntNode) { - return Type.INT; - } else if (node instanceof FloatNode) { - return Type.FLOAT; - } else if (node instanceof StringNode) { - return Type.STRING; - } else if (node instanceof IdentifierNode) { - // Lookup variable type in symbol table - // Assuming you have a method to get the variable type - // return getVariableTypeFromSymbolTable(((VariableReferenceNode) - // node).getName()); - } - // Handle more node types as necessary - - return Type.UNKNOWN; // Or any other default you want to assign - } - - // Define an exception class for semantic errors - public static class SemanticException extends Exception { - public SemanticException(String message) { - super(message); - } - } -} diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Type.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Type.java index 37d64cc..f259940 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Type.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Type.java @@ -7,6 +7,12 @@ public enum Type { BOOLEAN("boolean"), // Boolean type VOID("void"), // Type for functions that don't return a value // ... add other types as needed + COORD("coord"), + ENEMY("enemy"), + WALL("wall"), + FLOOR("floor"), + ROOM("room"), + UNKNOWN("unknown"); // Used for uninitialized or error states private final String typeName; diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index c669971..ed09d8d 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -6,18 +6,22 @@ public class TypeChecker { - HashMap typeOfReturnFunction; - HashMap > functionParameters; + HashMap typeOfReturnFunction; + HashMap> functionParameters; + List listOfInbuiltFunctions = new ArrayList<>(Arrays.asList("print", "generateGrid", "generateRooms", + "generateCorridors", "generateSpawns", "printMap", "generatePrint", "writeToFile", "overlap", + "tileInformationStringBuilder", "setSeed")); // HashMap fTable; // function table, identifier(x) og node + HashMap structTable; HashMap eTable;// variable table, identifier(x) og node(int) Stack> scopes; // scope table, variable identifier(x) og node Deque activeScope;// Hvilket scope vi er i nu int errorNumber = 1; Boolean printDebugger = false; Boolean hasReturnStatement = false; - String currentActiveFunction =""; + String currentActiveFunction = ""; public TypeChecker() { // fTable = new HashMap<>(); @@ -28,6 +32,7 @@ public TypeChecker() { scopes.add(eTable); typeOfReturnFunction = new HashMap<>(); functionParameters = new HashMap<>(); + structTable = new HashMap<>(); } public void visitor(AstNode node) { @@ -43,7 +48,7 @@ public void visitProgramNode(ProgramNode node) { } public void visitStatements(StatementNode node) { - if(printDebugger){ + if (printDebugger) { System.out.println("We get in the vist statement"); System.out.println(node.getClass()); System.out.println(node.getNode().getClass()); @@ -63,23 +68,25 @@ public void visitStatements(StatementNode node) { if (node.getNode() instanceof FunctionDefinitionNode) { visitFunctionDefinition((FunctionDefinitionNode) node.getNode()); } - if (node.getNode() instanceof FunctionCallNode){ + if (node.getNode() instanceof FunctionCallNode) { visitFunctionCall((FunctionCallNode) node.getNode()); } - if (node.getNode() instanceof ReturnStatementNode){ + if (node.getNode() instanceof ReturnStatementNode) { hasReturnStatement = true; - - System.out.println("we get in return statement"+ hasReturnStatement); + System.out.println("we get in return statement" + hasReturnStatement); visitReturnNode((ReturnStatementNode) node.getNode()); - + } + if(node.getNode() instanceof StructureDefinitionNode){ + visitStruct((StructureDefinitionNode) node.getNode()); } } - public void errorHandler(String errorMessage){ + public void errorHandler(String errorMessage) { System.err.println("Error " + errorNumber); errorNumber = errorNumber + 1; System.err.println(errorMessage); } + public Type relationOperatorTypeCheck(RelationsAndLogicalOperatorNode node) { AstNode left = node.getLeft(); @@ -98,7 +105,7 @@ public Type relationOperatorTypeCheck(RelationsAndLogicalOperatorNode node) { } else if (leftType == Type.BOOLEAN && rightType == Type.BOOLEAN) { return Type.BOOLEAN; } - + errorHandler("Wrong types for relation operation:" + leftType + ":" + left + " And:" + right + ":" + rightType); return Type.VOID; @@ -150,8 +157,8 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { } else { errorHandler("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier - + " that has the type:" + variableType - + " And that is hella iligal"); + + " that has the type:" + variableType + + " And that is hella iligal"); } } else { @@ -177,49 +184,49 @@ public Type getVariable(IdentifierNode node) { // Check if return = type er det samme som den function den står i. public void visitReturnNode(ReturnStatementNode node) { - Type returnType = getType(node.getReturnValue()); - Type activeFunction = typeOfReturnFunction.get(currentActiveFunction); - if(Objects.equals(currentActiveFunction, "")){ - errorHandler("You have made return statement outside a function THAT IS illigal"); - } - if(returnType != activeFunction){ - errorHandler("The return type " + returnType + " Does not match the return statement of the function " + activeFunction.getTypeName()); - } + Type returnType = getType(node.getReturnValue()); + Type activeFunction = typeOfReturnFunction.get(currentActiveFunction); + if (Objects.equals(currentActiveFunction, "")) { + errorHandler("You have made return statement outside a function THAT IS illigal"); + } + if (returnType != activeFunction) { + errorHandler("The return type " + returnType + " Does not match the return statement of the function " + activeFunction.getTypeName()); + } } public void visitAssignNode(AssignmentNode node) { - if(printDebugger){ + if (printDebugger) { } boolean foundIdentifier = false; for (HashMap ETable : scopes) { - if(true){ - System.out.println("Identifier"+node.getIdentifier().toString()); - System.out.println("Etable:"+ETable); - } - if (ETable.containsKey(node.getIdentifier().toString())) {// hvis x er i scope - foundIdentifier = true; + if (true) { + System.out.println("Identifier" + node.getIdentifier().toString()); + System.out.println("Etable:" + ETable); + } + if (ETable.containsKey(node.getIdentifier().toString())) {// hvis x er i scope + foundIdentifier = true; // tjekke om det er lovligt. // hent gamle type og nye type. Type oldType = getType(node.getIdentifier()); String identifier = node.getIdentifier().toString(); Type rightType = getType(node.getValue()); - + // tjekke om det er lovligt. if (oldType != rightType) { errorHandler("Tryied to asssign Type:" + rightType + " to the variable:" + identifier - + " that has the type:" + oldType - + " And that is hella iligal"); + + " that has the type:" + oldType + + " And that is hella iligal"); } - } else { + } else { errorHandler("Variable '" + node.getIdentifier() + "' has not been defined yet."); - } - if (foundIdentifier){ - break; - } + } + if (foundIdentifier) { + break; + } } } @@ -231,15 +238,15 @@ public void visitAssignNode(AssignmentNode node) { public void visitIfStatement(IfStatementNode node) { Type expression = Type.VOID; - if(printDebugger){ + if (printDebugger) { System.out.println("We get in the If statement"); } - + for (int i = 0; i < node.getExpressions().size(); i++) { - if(printDebugger){ + if (printDebugger) { System.out.println("We get in first for loop"); - System.out.println("Number of expressions:"+node.getExpressions().size()); + System.out.println("Number of expressions:" + node.getExpressions().size()); } expression = getType(node.getExpressions().get(i).getNode()); if (expression != Type.BOOLEAN) { @@ -248,9 +255,9 @@ public void visitIfStatement(IfStatementNode node) { } } for (int i = 0; i < node.getBlocks().size(); i++) { - if(printDebugger){ + if (printDebugger) { System.out.println("We get in 2 for loop"); - System.out.println("Number of blocks:"+node.getBlocks().size()); + System.out.println("Number of blocks:" + node.getBlocks().size()); } HashMap localETable = new HashMap<>(); scopes.add(localETable); @@ -274,45 +281,50 @@ public void visitWhileLoop(WhileLoopNode node) { } public void visitFunctionDefinition(FunctionDefinitionNode node) { - System.out.println(node+"We get in here"); - if (!typeOfReturnFunction.containsKey(node.toString()) && !functionParameters.containsKey(node.toString())) { - typeOfReturnFunction.put(node.getIdentifier().toString(), getType(node.getReturnType())); // Key identifier // Type - functionParameters.put(node.getIdentifier().toString(), new ArrayList<>()); - - HashMap localTable = new HashMap<>(); - scopes.add(localTable); - List parameters = node.getArguments().getParameters(); - for (ParameterNode parameter : parameters) { - String identifierParameter = String.valueOf((parameter.getIdentifier())); // int carl - Type arguementType = getType(parameter.getType()); - if(localTable.containsKey(identifierParameter) ){ - errorHandler("The variable:"+identifierParameter+" Already exist in this function parameters."); - } else { - scopes.getLast().put(identifierParameter, arguementType); - functionParameters.get(node.getIdentifier().toString()).add(arguementType);// Den tilføjer typen til listen. Fn x tilføjet int x, int x, int x + // System.out.println(node + "We get in here"); + if (!listOfInbuiltFunctions.contains(node.getIdentifier().toString())) { + if (!typeOfReturnFunction.containsKey(node.toString()) && !functionParameters.containsKey(node.toString())) { + typeOfReturnFunction.put(node.getIdentifier().toString(), getType(node.getReturnType())); // Key identifier // Type + functionParameters.put(node.getIdentifier().toString(), new ArrayList<>()); + + HashMap localTable = new HashMap<>(); + scopes.add(localTable); + List parameters = node.getArguments().getParameters(); + for (ParameterNode parameter : parameters) { + String identifierParameter = String.valueOf((parameter.getIdentifier())); // int carl + Type arguementType = getType(parameter.getType()); + if (localTable.containsKey(identifierParameter)) { + errorHandler("The variable:" + identifierParameter + " Already exist in this function parameters."); + } else { + scopes.getLast().put(identifierParameter, arguementType); + functionParameters.get(node.getIdentifier().toString()).add(arguementType);// Den tilføjer typen til listen. Fn x tilføjet int x, int x, int x + } } + currentActiveFunction = node.getIdentifier().toString(); + hasReturnStatement = false; + visitBlockNode(node.getBlock());// Alle statement i fn. En af dem er returnStatement + currentActiveFunction = ""; + if (!hasReturnStatement && Type.VOID != getType(node.getReturnType())) { + errorHandler("Missing return statement in function declartion:" + node.getIdentifier().toString()); + } + hasReturnStatement = false; + scopes.remove(localTable); + } else { + errorHandler("function " + node.getIdentifier() + " already exists"); } - currentActiveFunction = node.getIdentifier().toString(); - hasReturnStatement = false; - visitBlockNode(node.getBlock());// Alle statement i fn. En af dem er returnStatement - currentActiveFunction = ""; - if(!hasReturnStatement && Type.VOID != getType(node.getReturnType())){ - errorHandler("Missing return statement in function declartion:"+node.getIdentifier().toString()); - } - hasReturnStatement = false; - scopes.remove(localTable); } else { - errorHandler("function " + node.getIdentifier() + " already exists"); + errorHandler("You may not redeclare a inbuilt function. The function you tried to redeclare is:" + node.getIdentifier().toString()); } } - /* - * Vi skal sammenligne argumenterne med paremetrene. - * Vi skal tjekke at der lige mange. - * Der mangler fx argumenter der er ikke nok. eller der for mange. - * Vi skal sige hvis arguemtnet er en forkert type. - * */ + + /* + * Vi skal sammenligne argumenterne med paremetrene. + * Vi skal tjekke at der lige mange. + * Der mangler fx argumenter der er ikke nok. eller der for mange. + * Vi skal sige hvis arguemtnet er en forkert type. + * */ public void visitFunctionCall(FunctionCallNode node) { - if(!Objects.equals(node.getFunctionName().toString(), "print")) { + if (!listOfInbuiltFunctions.contains(node.getFunctionName().toString())) { HashMap localETable = new HashMap<>(); scopes.add(localETable); if (typeOfReturnFunction.containsKey(node.getFunctionName().toString())) { @@ -320,13 +332,12 @@ public void visitFunctionCall(FunctionCallNode node) { int expectedArgumentsSize = expectedParameterTypes.size(); int actualArgumentsSize = node.getArguments().size(); - if(expectedArgumentsSize != actualArgumentsSize){ - errorHandler("Function Expected:"+expectedArgumentsSize+" Arguments but got :"+actualArgumentsSize+" Arguments"); + if (expectedArgumentsSize != actualArgumentsSize) { + errorHandler("Function Expected:" + expectedArgumentsSize + " Arguments but got :" + actualArgumentsSize + " Arguments"); } - for (int i = 0; i < expectedArgumentsSize; i++) { if (expectedParameterTypes.get(i) != getType(node.getArgument(i))) { - errorHandler("Function Expected type: " + expectedParameterTypes.get(i) + ", as "+ i + " Argument but got " + getType(node.getArgument(i))); + errorHandler("Function Expected type: " + expectedParameterTypes.get(i) + ", as " + i + " Argument but got " + getType(node.getArgument(i))); } } @@ -336,6 +347,23 @@ public void visitFunctionCall(FunctionCallNode node) { } } + + public void visitStruct(StructureDefinitionNode node) { + + if (!structTable.containsKey(node.getIdentifier().toString())) { + structTable.put(node.getIdentifier().toString(), getType(node.getType())); + } else { + errorHandler("function " + node.getIdentifier().toString() + " already exists"); + } + HashMap localETable = new HashMap<>(); + scopes.add(localETable); + List declarations = node.getVariableDeclarations(); + for (VariableDeclarationNode declaration : declarations) { + visitVariableDeclaration(declaration); + } + scopes.remove(localETable); + } + public void visitBlockNode(BlockNode node) { for (AstNode statement : node.getStatements()) { visitStatements((StatementNode) statement); @@ -356,12 +384,10 @@ public Type getType(Object node) { type = binaryOperatorTypeCheck((BinaryOperatorNode) node); } else if (node instanceof RelationsAndLogicalOperatorNode) { type = relationOperatorTypeCheck((RelationsAndLogicalOperatorNode) node); - } else if (node instanceof FunctionCallNode){ + } else if (node instanceof FunctionCallNode) { String variableName = ((FunctionCallNode) node).getFunctionName().toString(); type = typeOfReturnFunction.get(variableName); - } - - else if (node instanceof IntNode) { + } else if (node instanceof IntNode) { type = Type.INT; } else if (node instanceof FloatNode) { type = Type.FLOAT; @@ -396,6 +422,28 @@ else if (node instanceof IntNode) { return Type.BOOLEAN; } + } else if (node instanceof String) { + String typeAsString = ((String) node); + switch (typeAsString) { + case "int": + return Type.INT; + case "string": + return Type.STRING; + case "bool": + return Type.BOOLEAN; + case "float": + return Type.FLOAT; + case "enemy": + return Type.ENEMY; + case "floor": + return Type.FLOOR; + case "wall": + return Type.WALL; + case "room": + return Type.ROOM; + default: + break; + } } else { errorHandler("The node we get failed to handle:" + node.getClass()); } diff --git a/test.carl b/test.carl index df35f66..e69de29 100644 --- a/test.carl +++ b/test.carl @@ -1,23 +0,0 @@ - -var Orc : enemy = { - var difficulty : int = 1 - var health : int = 200 - var symbol : string= "O" -} -var Goblin : enemy ={ - var difficulty : int = 1 - var health : int = 500 - var symbol : string= "O" -} -var Goblin2 : enemy ={ - var difficulty : int = 1 - var health : int = 500 - var symbol : string= "O" -} -var Goblin3 : enemy ={ - var difficulty : int = 1 - var health : int = 500 - var symbol : string= "O" -} -var test : int = 1..enemy.size() -print(test) From f524ad3e9dba78962ecc7b1098cd149619b0400c Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sat, 4 May 2024 21:00:00 +0200 Subject: [PATCH 40/94] =?UTF-8?q?Start=20p=C3=A5=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carl/Semantic_A/TypeChecker.java | 4 +- .../carl/Semantic_A/TypeCheckerTest.java | 196 ++++++++++++++++++ 2 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index ed09d8d..7355d22 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -108,7 +108,7 @@ public Type relationOperatorTypeCheck(RelationsAndLogicalOperatorNode node) { errorHandler("Wrong types for relation operation:" + leftType + ":" + left + " And:" + right + ":" + rightType); - return Type.VOID; + return Type.UNKNOWN; } public Type binaryOperatorTypeCheck(BinaryOperatorNode node) { @@ -128,7 +128,7 @@ public Type binaryOperatorTypeCheck(BinaryOperatorNode node) { return Type.FLOAT; } errorHandler("Wrong types for binary operation:" + leftType + ":" + left + " And:" + right + ":" + rightType); - return Type.VOID; + return Type.UNKNOWN; } diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java new file mode 100644 index 0000000..a2477a7 --- /dev/null +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -0,0 +1,196 @@ +package dk.aau.cs_24_sw_4_16.carl.Semantic_A; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; + +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTree; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import dk.aau.cs_24_sw_4_16.carl.CARLLexer; +import dk.aau.cs_24_sw_4_16.carl.CARLParser; +import dk.aau.cs_24_sw_4_16.carl.CstToAst.AstNode; +import dk.aau.cs_24_sw_4_16.carl.CstToAst.BinaryOperatorNode; +import dk.aau.cs_24_sw_4_16.carl.CstToAst.BoolNode; +import dk.aau.cs_24_sw_4_16.carl.CstToAst.CstToAstVisitor; +import dk.aau.cs_24_sw_4_16.carl.CstToAst.FloatNode; +import dk.aau.cs_24_sw_4_16.carl.CstToAst.IntNode; +import dk.aau.cs_24_sw_4_16.carl.CstToAst.RelationsAndLogicalOperatorNode; +import dk.aau.cs_24_sw_4_16.carl.CstToAst.StringNode; + +public class TypeCheckerTest { + + TypeChecker typeChecker = new TypeChecker(); + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final ByteArrayOutputStream errContent = new ByteArrayOutputStream(); + private final PrintStream originalErr = System.err; + + // Redirect System.err before each test + @BeforeEach + void setUpStreams() { + System.setErr(new PrintStream(errContent)); + } + + // Restore original System.err after each test + @AfterEach + void restoreStreams() { + System.setErr(originalErr); + } + + public AstNode treemaker(String fileInput) {// Denne her skal vi bruge til intergrations testing af Typechecker + AstNode astNode; + if (fileInput != null) { + try { + InputStream stream = new ByteArrayInputStream(fileInput.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + + CARLParser parser = new CARLParser(tokens); + + ParseTree tree = parser.program(); + + CstToAstVisitor visitor = new CstToAstVisitor(); + + astNode = visitor.visit(tree); + return astNode; + } catch (Exception e) { + System.out.println("Error happened:" + e); + } + + } + return null; + + } + + @Test + void testBinaryOperatorTypeCheck() { + + IntNode intNode = new IntNode(0); + BoolNode boolNode = new BoolNode(null); + StringNode stringNode = new StringNode(null); + FloatNode floatNode = new FloatNode("2.2"); + + BinaryOperatorNode testnode1 = new BinaryOperatorNode(intNode, intNode, null); + BinaryOperatorNode testnode2 = new BinaryOperatorNode(boolNode, stringNode, null); + BinaryOperatorNode testnode3 = new BinaryOperatorNode(floatNode, floatNode, null); + + Type testfn1 = typeChecker.binaryOperatorTypeCheck(testnode1); + Type testfn2 = typeChecker.binaryOperatorTypeCheck(testnode2); + Type testfn3 = typeChecker.binaryOperatorTypeCheck(testnode3); + + assertEquals(Type.INT, testfn1, "Should have returned int"); + assertEquals(Type.UNKNOWN, testfn2, "Should have returned unknown"); + assertEquals(Type.FLOAT, testfn3, "Should have returned float"); + + } + + @Test + void testErrorHandler() { + String testString = "test1"; + String testString2 = "test2"; + typeChecker.errorHandler(testString); + typeChecker.errorHandler(testString2); + String expectedOutput = "Error 1\n" + + "test1\n" + + "Error 2\n" + + "test2\n"; + // System.out.println(outContent.toString().trim()); + // System.err.println(expectedOutput.length()+"actual;"+errContent.toString().length()); + String normalizedActualOutput = errContent.toString().trim().replace("\r\n", "\n").replace("\r", "\n"); + assertEquals(expectedOutput.trim(), normalizedActualOutput); + } + + @Test + void testGetType() { + + } + + @Test + void testGetVariable() { + + } + + @Test + void testRelationOperatorTypeCheck() { + + IntNode intNode = new IntNode(0); + BoolNode boolNode = new BoolNode(null); + StringNode stringNode = new StringNode(null); + FloatNode floatNode = new FloatNode("2.2"); + + RelationsAndLogicalOperatorNode testnode1 = new RelationsAndLogicalOperatorNode(stringNode, floatNode, null); + RelationsAndLogicalOperatorNode testnode2 = new RelationsAndLogicalOperatorNode(boolNode, boolNode, null); + RelationsAndLogicalOperatorNode testnode3 = new RelationsAndLogicalOperatorNode(intNode, intNode, null); + Type testfn1 = typeChecker.relationOperatorTypeCheck(testnode1); + Type testfn2 = typeChecker.relationOperatorTypeCheck(testnode2); + Type testfn3 = typeChecker.relationOperatorTypeCheck(testnode3); + + assertEquals(Type.UNKNOWN, testfn1, "Should return Type unkown"); + assertEquals(Type.BOOLEAN, testfn2, "Should have Type bool"); + assertEquals(Type.BOOLEAN, testfn3, "Should have Type bool"); + } + + @Test + void testVisitAssignNode() { + + } + + @Test + void testVisitBlockNode() { + + } + + @Test + void testVisitFunctionCall() { + + } + + @Test + void testVisitFunctionDefinition() { + + } + + @Test + void testVisitIfStatement() { + + } + + @Test + void testVisitProgramNode() { + + } + + @Test + void testVisitReturnNode() { + + } + + @Test + void testVisitStatements() { + + } + + @Test + void testVisitStruct() { + + } + + @Test + void testVisitWhileLoop() { + + } + + @Test + void testVisitor() { + + } +} From 85365559a1995dd19bc85a87aac301ed6677a75e Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sat, 4 May 2024 21:05:02 +0200 Subject: [PATCH 41/94] =?UTF-8?q?Vi=20k=C3=B8rer=20ikke=20interpriter=20vi?= =?UTF-8?q?s=20typechecker=20smider=20fejl=20godt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/dk/aau/cs_24_sw_4_16/carl/Main.java | 24 +++++---- .../carl/Semantic_A/TypeChecker.java | 51 ++++++++++++------- test.carl | 1 + 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index eb3a445..e3c0082 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -35,25 +35,29 @@ public static void main(String... args) { // It returns a parse tree representing the entire input file. ParseTree tree = parser.program();// Her stopper det som Antler har lavet. - // CstToAstVisitor is a visitor class that converts the parse tree (CST) into an abstract syntax tree (AST). - // This is typically used to simplify and optimize the tree structure for further processing. + // CstToAstVisitor is a visitor class that converts the parse tree (CST) into an + // abstract syntax tree (AST). + // This is typically used to simplify and optimize the tree structure for + // further processing. CstToAstVisitor visitor = new CstToAstVisitor(); // The visit method walks the parse tree and constructs the AST AstNode astRoot = visitor.visit(tree); - System.out.println(astRoot); + //System.out.println(astRoot); TypeChecker typeChecker = new TypeChecker(); typeChecker.visitor(astRoot); - // Interpreter is a class that can traverse the AST and interpret or execute the program based on the AST. - Interpreter inter = new Interpreter(); + if (!typeChecker.thereWasAnError) { + Interpreter inter = new Interpreter(); + + inter.visit(astRoot); + } + // Interpreter is a class that can traverse the AST and interpret or execute the + // program based on the AST. - inter.visit(astRoot); - } - catch (IOException e) { + } catch (IOException e) { System.out.println(e.toString()); - } - catch (Exception e) { + } catch (Exception e) { // Catches any exception that occurs within the try block. // Prints the string representation of the exception to standard output. System.out.println(); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 7355d22..770edec 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -12,7 +12,8 @@ public class TypeChecker { "generateCorridors", "generateSpawns", "printMap", "generatePrint", "writeToFile", "overlap", "tileInformationStringBuilder", "setSeed")); - // HashMap fTable; // function table, identifier(x) og node + // HashMap fTable; // function table, + // identifier(x) og node HashMap structTable; HashMap eTable;// variable table, identifier(x) og node(int) @@ -22,9 +23,11 @@ public class TypeChecker { Boolean printDebugger = false; Boolean hasReturnStatement = false; String currentActiveFunction = ""; + public Boolean thereWasAnError = false; public TypeChecker() { -// fTable = new HashMap<>(); + + // fTable = new HashMap<>(); eTable = new HashMap<>(); scopes = new Stack<>(); activeScope = new ArrayDeque<>(); @@ -76,12 +79,13 @@ public void visitStatements(StatementNode node) { System.out.println("we get in return statement" + hasReturnStatement); visitReturnNode((ReturnStatementNode) node.getNode()); } - if(node.getNode() instanceof StructureDefinitionNode){ + if (node.getNode() instanceof StructureDefinitionNode) { visitStruct((StructureDefinitionNode) node.getNode()); } } public void errorHandler(String errorMessage) { + thereWasAnError = true; System.err.println("Error " + errorNumber); errorNumber = errorNumber + 1; System.err.println(errorMessage); @@ -182,7 +186,7 @@ public Type getVariable(IdentifierNode node) { throw new RuntimeException("could not find the variable " + node.getIdentifier()); } - // Check if return = type er det samme som den function den står i. + // Check if return = type er det samme som den function den står i. public void visitReturnNode(ReturnStatementNode node) { Type returnType = getType(node.getReturnValue()); Type activeFunction = typeOfReturnFunction.get(currentActiveFunction); @@ -190,7 +194,8 @@ public void visitReturnNode(ReturnStatementNode node) { errorHandler("You have made return statement outside a function THAT IS illigal"); } if (returnType != activeFunction) { - errorHandler("The return type " + returnType + " Does not match the return statement of the function " + activeFunction.getTypeName()); + errorHandler("The return type " + returnType + " Does not match the return statement of the function " + + activeFunction.getTypeName()); } } @@ -283,21 +288,28 @@ public void visitWhileLoop(WhileLoopNode node) { public void visitFunctionDefinition(FunctionDefinitionNode node) { // System.out.println(node + "We get in here"); if (!listOfInbuiltFunctions.contains(node.getIdentifier().toString())) { - if (!typeOfReturnFunction.containsKey(node.toString()) && !functionParameters.containsKey(node.toString())) { - typeOfReturnFunction.put(node.getIdentifier().toString(), getType(node.getReturnType())); // Key identifier // Type + if (!typeOfReturnFunction.containsKey(node.toString()) + && !functionParameters.containsKey(node.toString())) { + typeOfReturnFunction.put(node.getIdentifier().toString(), getType(node.getReturnType())); // Key + // identifier + // // Type functionParameters.put(node.getIdentifier().toString(), new ArrayList<>()); HashMap localTable = new HashMap<>(); scopes.add(localTable); List parameters = node.getArguments().getParameters(); for (ParameterNode parameter : parameters) { - String identifierParameter = String.valueOf((parameter.getIdentifier())); // int carl + String identifierParameter = String.valueOf((parameter.getIdentifier())); // int carl Type arguementType = getType(parameter.getType()); if (localTable.containsKey(identifierParameter)) { - errorHandler("The variable:" + identifierParameter + " Already exist in this function parameters."); + errorHandler( + "The variable:" + identifierParameter + " Already exist in this function parameters."); } else { scopes.getLast().put(identifierParameter, arguementType); - functionParameters.get(node.getIdentifier().toString()).add(arguementType);// Den tilføjer typen til listen. Fn x tilføjet int x, int x, int x + functionParameters.get(node.getIdentifier().toString()).add(arguementType);// Den tilføjer typen + // til listen. Fn x + // tilføjet int x, + // int x, int x } } currentActiveFunction = node.getIdentifier().toString(); @@ -313,16 +325,17 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { errorHandler("function " + node.getIdentifier() + " already exists"); } } else { - errorHandler("You may not redeclare a inbuilt function. The function you tried to redeclare is:" + node.getIdentifier().toString()); + errorHandler("You may not redeclare a inbuilt function. The function you tried to redeclare is:" + + node.getIdentifier().toString()); } } /* * Vi skal sammenligne argumenterne med paremetrene. * Vi skal tjekke at der lige mange. - * Der mangler fx argumenter der er ikke nok. eller der for mange. + * Der mangler fx argumenter der er ikke nok. eller der for mange. * Vi skal sige hvis arguemtnet er en forkert type. - * */ + */ public void visitFunctionCall(FunctionCallNode node) { if (!listOfInbuiltFunctions.contains(node.getFunctionName().toString())) { HashMap localETable = new HashMap<>(); @@ -333,21 +346,23 @@ public void visitFunctionCall(FunctionCallNode node) { int expectedArgumentsSize = expectedParameterTypes.size(); int actualArgumentsSize = node.getArguments().size(); if (expectedArgumentsSize != actualArgumentsSize) { - errorHandler("Function Expected:" + expectedArgumentsSize + " Arguments but got :" + actualArgumentsSize + " Arguments"); + errorHandler("Function Expected:" + expectedArgumentsSize + " Arguments but got :" + + actualArgumentsSize + " Arguments"); } for (int i = 0; i < expectedArgumentsSize; i++) { if (expectedParameterTypes.get(i) != getType(node.getArgument(i))) { - errorHandler("Function Expected type: " + expectedParameterTypes.get(i) + ", as " + i + " Argument but got " + getType(node.getArgument(i))); + errorHandler("Function Expected type: " + expectedParameterTypes.get(i) + ", as " + i + + " Argument but got " + getType(node.getArgument(i))); } } } else { - errorHandler("The function :" + node.getFunctionName().toString() + " May not exist or be out of scope."); + errorHandler( + "The function :" + node.getFunctionName().toString() + " May not exist or be out of scope."); } } } - public void visitStruct(StructureDefinitionNode node) { if (!structTable.containsKey(node.getIdentifier().toString())) { @@ -373,7 +388,7 @@ public void visitBlockNode(BlockNode node) { public Type getType(Object node) { Type type = Type.VOID; - if (node instanceof IdentifierNode) { // true bool node. true identifier node + if (node instanceof IdentifierNode) { // true bool node. true identifier node if ("true".equals(node.toString()) || "false".equals(node.toString())) { type = Type.BOOLEAN; } else { diff --git a/test.carl b/test.carl index e69de29..3c7842c 100644 --- a/test.carl +++ b/test.carl @@ -0,0 +1 @@ +var number:int = 20 From 4171bf063e1895a38eb66cc21ae161cc7db87c06 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sat, 4 May 2024 21:40:37 +0200 Subject: [PATCH 42/94] vi gemmer struct variables og struct type --- .../java/dk/aau/cs_24_sw_4_16/carl/Main.java | 4 +- .../carl/Semantic_A/TypeChecker.java | 78 +++- .../carl/Semantic_A/Visitor.java | 357 ------------------ test.carl | 13 + 4 files changed, 79 insertions(+), 373 deletions(-) delete mode 100644 src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index e3c0082..2cd6206 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -46,10 +46,10 @@ public static void main(String... args) { TypeChecker typeChecker = new TypeChecker(); typeChecker.visitor(astRoot); - + System.out.println("error"); if (!typeChecker.thereWasAnError) { Interpreter inter = new Interpreter(); - + System.out.println("no error"); inter.visit(astRoot); } // Interpreter is a class that can traverse the AST and interpret or execute the diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 770edec..480b063 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -11,11 +11,11 @@ public class TypeChecker { List listOfInbuiltFunctions = new ArrayList<>(Arrays.asList("print", "generateGrid", "generateRooms", "generateCorridors", "generateSpawns", "printMap", "generatePrint", "writeToFile", "overlap", "tileInformationStringBuilder", "setSeed")); - + HashMap> strucvariablesTable; + HashMap structTypes; // HashMap fTable; // function table, // identifier(x) og node - HashMap structTable; HashMap eTable;// variable table, identifier(x) og node(int) Stack> scopes; // scope table, variable identifier(x) og node Deque activeScope;// Hvilket scope vi er i nu @@ -23,7 +23,7 @@ public class TypeChecker { Boolean printDebugger = false; Boolean hasReturnStatement = false; String currentActiveFunction = ""; - public Boolean thereWasAnError = false; + public Boolean thereWasAnError = false; public TypeChecker() { @@ -35,7 +35,8 @@ public TypeChecker() { scopes.add(eTable); typeOfReturnFunction = new HashMap<>(); functionParameters = new HashMap<>(); - structTable = new HashMap<>(); + strucvariablesTable = new HashMap<>(); + structTypes = new HashMap<>(); } public void visitor(AstNode node) { @@ -363,20 +364,69 @@ public void visitFunctionCall(FunctionCallNode node) { } } + /* + * Check om den eksistere + * Deklerere den til sidst. fordi kun vis alle variabler i den er okay + * check variabler + * hvis de ok gem dem i hashmap + * Skal også tjekke type af Struct i guess + */ public void visitStruct(StructureDefinitionNode node) { + String identifier = node.getIdentifier().toString(); + System.out.println("structtypes"+structTypes); + if (!strucvariablesTable.containsKey(identifier)) { + + + Type structType =getType(node.getType()); + + HashMap localETable = new HashMap<>(); - if (!structTable.containsKey(node.getIdentifier().toString())) { - structTable.put(node.getIdentifier().toString(), getType(node.getType())); + scopes.add(localETable); + + List declarations = node.getVariableDeclarations(); + for (VariableDeclarationNode declaration : declarations) { + visitVariableDeclarationforStructs(declaration); + } + structTypes.put(identifier, structType); + strucvariablesTable.put(identifier, localETable); + scopes.remove(localETable); + } else { - errorHandler("function " + node.getIdentifier().toString() + " already exists"); + errorHandler("Struct " + node.getIdentifier().toString() + " already exists"); } - HashMap localETable = new HashMap<>(); - scopes.add(localETable); - List declarations = node.getVariableDeclarations(); - for (VariableDeclarationNode declaration : declarations) { - visitVariableDeclaration(declaration); + System.out.println(strucvariablesTable); + } + + private void visitVariableDeclarationforStructs(VariableDeclarationNode node) { + try { + boolean found = scopes.getLast().containsKey(node.getIdentifier().toString()); + + if (!found) {// Vi skal tjekke variable type mod det den type vi assigner til variablen. + + String identifier = node.getIdentifier().toString(); + + Type variableType = getType(node.getType()); // Left side type + + AstNode ass = node.getValue(); // THis is right side should be a node + Type assignmentType = getType(ass); // This should give right side type + + if (variableType == assignmentType) { + Type typeWeSaveInETable = variableType; + scopes.getLast().put(node.getIdentifier().toString(), typeWeSaveInETable); + + } else { + errorHandler("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + + " that has the type:" + variableType + + " And that is hella iligal"); + + } + } else { + throw new RuntimeException("variable " + node.getIdentifier() + " already exists in struct"); + } + } catch (Exception e) { + errorHandler(e.getMessage()); } - scopes.remove(localETable); + } public void visitBlockNode(BlockNode node) { @@ -386,7 +436,7 @@ public void visitBlockNode(BlockNode node) { } public Type getType(Object node) { - Type type = Type.VOID; + Type type = Type.UNKNOWN; if (node instanceof IdentifierNode) { // true bool node. true identifier node if ("true".equals(node.toString()) || "false".equals(node.toString())) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java deleted file mode 100644 index bfb5bce..0000000 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/Visitor.java +++ /dev/null @@ -1,357 +0,0 @@ -package dk.aau.cs_24_sw_4_16.carl.Semantic_A; - -import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; -import java.util.*; -import dk.aau.cs_24_sw_4_16.carl.Interpreter.InbuildClasses;; - -public class Visitor { -// HashMap fTable; // function table, identifier(x) og node -// HashMap ETable;// variable table, identifier(x) og node(int) -// Stack> scopes; // scope table, variable identifier(x) og node -// Deque activeScope;// Hvilket scope vi er i nu -// -// boolean printypes = true;// ! SLET SENERE -// -// public AstNode visit(AstNode node) { -// if (node instanceof ProgramNode) { -// if (printypes) { -// System.out.println("Hej jeg kommer int i visitor"); -// } -// fTable = new HashMap<>(); -// ETable = new HashMap<>(); -// scopes = new Stack<>(); -// activeScope = new ArrayDeque<>(); -// activeScope.push(0); -// scopes.add(ETable); -// -// return visit((ProgramNode) node); -// } else if (node instanceof StatementNode) { -// return visit((StatementNode) node); -// } else if (node instanceof ExpressionNode) { -// return visit((ExpressionNode) node); -// } -// return node; -// } -// -// public void visit(StatementNode node) { -// if (node.getNode() instanceof AssignmentNode) { -// visit((AssignmentNode) node.getNode()); -// } else if (node.getNode() instanceof VariableDeclarationNode) { -// visit((VariableDeclarationNode) node.getNode()); -// } else if (node.getNode() instanceof FunctionCallNode) { -// return visit((FunctionCallNode) node.getNode()); -// } else if (node.getNode() instanceof FunctionDefinitionNode) { -// return visit((FunctionDefinitionNode) node.getNode()); -// } else if (node.getNode() instanceof WhileLoopNode) { -// return visit((WhileLoopNode) node.getNode()); -// } else if (node.getNode() instanceof IfStatementNode) { -// visit((IfStatementNode) node.getNode()); -// } else if (node.getNode() instanceof BinaryOperatorNode) { -// visit((BinaryOperatorNode) node.getNode()); -// if (true) { -// System.out.println("Hej jeg kommer int i interpriter binaryoperator"); -// } -// } else if (node.getNode() instanceof ReturnStatementNode) { -// return visit((ReturnStatementNode) node.getNode()); -// } -// -// } -// -// public AstNode visit(ReturnStatementNode node) { -// return node; -// } -// -// public void visit(IfStatementNode node) { -// HashMap localTable = new HashMap<>(); // ny lokalt value table -// scopes.add(localTable); // Tilføjer det til stacken med scopes -// boolean visited = false; -// for (int i = 0; i < node.getExpressions().size(); i++) { // Hver expression er en if statement. Ligesom hver -// // block er til den if statement -// AstNode toCheck = node.getExpressions().get(i).getNode(); -// if (node.getExpressions().get(i).getNode() instanceof IdentifierNode) { -// toCheck = getVariable((IdentifierNode) node.getExpressions().get(i).getNode());// Hvis det er x så giv -// // mig xnode -// } else if (node.getExpressions().get(i).getNode() instanceof RelationsAndLogicalOperatorNode) { -// toCheck = visit((RelationsAndLogicalOperatorNode) node.getExpressions().get(i).getNode()); -// } -// if (toCheck instanceof BoolNode && ((BoolNode) toCheck).getValue()) { -// visit(node.getBlocks().get(i)); -// visited = true; -// break; -// } -// } -// if (!visited && node.getExpressions().size() < node.getBlocks().size()) { -// visit(node.getBlocks().get(node.getBlocks().size() - 1)); -// } -// scopes.remove(localTable); -// } -// -// public Type getVariable(IdentifierNode node) { -// // for (HashMap vTable : scopes) { -// if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { // Tester om x er der, ev til bool -// return scopes.getFirst().get(node.getIdentifier().toString());// i scope, giv mig x node -// } -// -// for (int i = activeScope.getLast(); i < scopes.size(); i++) {// for at gå igennem hvert scope og tjekke for x -// if (scopes.get(i).containsKey(node.getIdentifier().toString())) { -// return scopes.get(i).get(node.getIdentifier().toString());// i i scope, giv mig x node -// } -// } -// throw new RuntimeException("could not find the variable " + node.getIdentifier()); -// } -// -// public void visit(AssignmentNode node) { -// -// for (HashMap vTable : scopes) { -// if (vTable.containsKey(node.getIdentifier().toString())) { // tjek if variable x is scopes bool -// AstNode nodeToChange = vTable.get(node.getIdentifier().toString());// retunere node -// AstNode toChange = node.getValue(); // Højre side af assignmen x= tochange vil retunere node -// if (toChange instanceof BinaryOperatorNode) { -// toChange = visit((BinaryOperatorNode) toChange); // if x= 20+20 -// } -// if (toChange instanceof FunctionCallNode) { -// toChange = visit((FunctionCallNode) toChange); // if x= functioncall(10) -// } -// if (toChange instanceof IdentifierNode) { -// toChange = getVariable((IdentifierNode) toChange); // if x = y -// } -// if (node.getValue() instanceof RelationsAndLogicalOperatorNode) { // if x= 10<5 -// toChange = visit((RelationsAndLogicalOperatorNode) toChange); -// } -// AstNode finalToChange = toChange; -// switch (nodeToChange) { -// case IntNode intNode when finalToChange instanceof IntNode -> -// intNode.setValue(((IntNode) finalToChange).getValue()); -// case FloatNode floatNode when finalToChange instanceof FloatNode -> -// floatNode.setValue(((FloatNode) finalToChange).getValue()); -// case StringNode stringNode when finalToChange instanceof StringNode -> -// stringNode.setValue(((StringNode) finalToChange).getValue()); -// case BoolNode boolNode when finalToChange instanceof BoolNode -> -// boolNode.setValue(((BoolNode) finalToChange).getValue()); -// case null, default -> throw new RuntimeException("Type mismatch"); -// } -// return; -// } -// } -// -// throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); -// } -// -// public void visit(VariableDeclarationNode node) { -// boolean found = false; -// if (scopes.getFirst().containsKey(node.getIdentifier().toString())) {// finder x i scope FY FY -// found = true; -// } -// -// for (int i = activeScope.getLast(); i < scopes.size(); i++) {// finder x i et scope FY FY -// if (scopes.get(i).containsKey(node.getIdentifier().toString())) { -// found = true; -// } -// } -// if (!found) { // kunne ikke finde x i scope så kan gemme den -// -// AstNode toChange = node.getValue(); // x=value value = node eller 5 -// if (node.getValue() instanceof BinaryOperatorNode) { // hvis x=2+2 -// toChange = visit((BinaryOperatorNode) node.getValue()); // Henter type node efter operation node -// scopes.getLast().put(node.getIdentifier().toString(), toChange); // Her sætter vi x til type node i -// // scope hash map -// } else if (toChange instanceof IdentifierNode) { // Vis x=y -// for (HashMap vTable : scopes) {// For hvert scope skal vi prøve at finde variable -// if (vTable.containsKey(toChange.toString())) {// Vis vi finder den i et scope -// scopes.getLast().put(node.getIdentifier().toString(), vTable.get(toChange.toString())); -// } -// } -// } else { -// scopes.getLast().put(node.getIdentifier().toString(), toChange); // case hvor x=4 -// } -// -// } else { // Fy fy den findes allerede -// throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); -// } -// } -// -// public AstNode visit(TypeNode node) { -// return node; -// } -// -// public AstNode visit(BoolNode node) { -// return node; -// } -// -// public AstNode visit(IntNode node) { -// return node; -// } -// -// public AstNode visit(FloatNode node) { -// return node; -// } -// -// public AstNode visit(ProgramNode node) { -// for (AstNode statement : node.getStatements()) { -// visit(statement); -// } -// return node; -// } -// -// public void visit(FunctionCallNode node) { -// if (node.getFunctionName().toString().equals("print")) { -// InbuildClasses.print(node, scopes, activeScope); -// } else { -// HashMap localTable = new HashMap<>(); -// scopes.add(localTable); -// activeScope.add(scopes.size() - 1); -// -// if (fTable.containsKey(node.getFunctionName().toString())) { -// FunctionDefinitionNode function = fTable.get(node.getFunctionName().toString()); -// List arguments = function.getArguments().getParameters(); -// for (int i = 0; i < function.getArguments().getParameters().size(); i++) { -// visit(new VariableDeclarationNode(arguments.get(i).getIdentifier(), arguments.get(i).getType(), -// node.getArgument(i))); -// } -// AstNode test = visit(function.getBlock());//! Denne her skal have statements -// -// if (test instanceof ReturnStatementNode) { -// AstNode returnValue = ((ReturnStatementNode) test).getReturnValue(); -// if (returnValue instanceof IdentifierNode) { -// returnValue = getVariable((IdentifierNode) returnValue); -// } -// scopes.remove(localTable); -// activeScope.removeLast(); -// if (function.getReturnType().getType().equals("void")) { -// if (returnValue != null) { -// throw new RuntimeException( -// "cannot return a value in void function call or have code after return statement"); -// } -// return node; -// } -// -// return returnValue; -// } -// } -// } -// return node; -// } -// -// public void visit(BlockNode node) { -// for (AstNode statement : node.getStatements()) { -// -// if (((StatementNode) statement).getNode() instanceof ReturnStatementNode) { -// visit((StatementNode) statement); -// } else { -// visit((StatementNode) statement); -// } -// } -// } -// -// public void visit(ExpressionNode node) { -// if (node.getNode() instanceof FunctionCallNode) { -// visit((FunctionCallNode) node.getNode()); -// } else if (node.getNode() instanceof RelationsAndLogicalOperatorNode) { -// visit((RelationsAndLogicalOperatorNode) node.getNode()); -// } else if (node.getNode() instanceof BinaryOperatorNode) { -// visit((BinaryOperatorNode) node.getNode()); -// } -// } -// -// public void visit(FunctionDefinitionNode node) { -// if (!fTable.containsKey(node.getIdentifier().toString())) { -// fTable.put(node.getIdentifier().toString(), node); -// } else { -// throw new RuntimeException("function " + node.getIdentifier() + " already exists"); -// } -// } -// -// public Type binaryoperator_type_check(BinaryOperatorNode node) { -// AstNode left = node.getLeft(); // Får venstre x som i result=x+y i node form -// AstNode right = node.getRight();// Får højre y i node form -// -// Type left_type = Type.VOID; -// Type right_Type = Type.VOID; -// -// left_type = getType(left); -// right_Type = getType(right); -// -// // Lav type check her. -// -// if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. -// return Type.INT; -// } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { -// return Type.FLOAT; -// } -// System.out.println( -// "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); -// return Type.VOID; -// } -// -// public Type relationOperator_Type_check(RelationsAndLogicalOperatorNode node) { -// -// AstNode left = node.getLeft(); -// AstNode right = node.getRight(); -// -// Type left_type = Type.VOID; -// Type right_Type = Type.VOID; -// -// left_type = getType(left); -// right_Type = getType(right); -// -// if (left_type == Type.INT && right_Type == Type.INT) { // Her at udregning sker, som ikke burde ske. -// return Type.BOOLEAN; -// } else if (left_type == Type.FLOAT && right_Type == Type.FLOAT) { -// return Type.BOOLEAN; -// } else if (left_type == Type.BOOLEAN && right_Type == Type.BOOLEAN) { -// return Type.BOOLEAN; -// } -// -// System.out.println( -// "Wrong types for binnary operation:" + left_type + ":" + left + " And:" + right + ":" + right_Type); -// return Type.VOID; -// } -// -// public Type getType(AstNode node) { -// Type type = Type.VOID; -// -// if (node instanceof IdentifierNode) { -// type = getVariable((IdentifierNode) node); // Vis x giv mig x value -// } else if (node instanceof BinaryOperatorNode) { -// type = binaryoperator_type_check((BinaryOperatorNode) node); -// } else if (node instanceof IntNode) { -// type = Type.INT; -// } else if (node instanceof FloatNode) { -// type = Type.FLOAT; -// } else if (node instanceof BoolNode) { -// type = Type.BOOLEAN; -// } else if (node instanceof ExpressionNode){ -// if(((ExpressionNode) node).getNode() instanceof BinaryOperatorNode){ -// type = binaryoperator_type_check((BinaryOperatorNode) node); -// } else if (((ExpressionNode) node).getNode() instanceof RelationsAndLogicalOperatorNode){ -// type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) node); -// } -// } -// return type; -// } -// -// public void visit(WhileLoopNode node) { // ! Type cheking her er at checke expression while(expresion) sikre at det -// // er en bool type -// AstNode toCheck = (node.getExpression()).getNode(); -// Type tocheck_type = Type.VOID; -// -// if (toCheck instanceof IdentifierNode) { -// tocheck_type = getVariable((IdentifierNode) node.getExpression().getNode()); // skal evaluere til bool -// } else if (toCheck instanceof RelationsAndLogicalOperatorNode) { -// tocheck_type = relationOperator_Type_check((RelationsAndLogicalOperatorNode) toCheck); // skal også til bool -// } -// if (toCheck instanceof BoolNode) { -// tocheck_type = Type.BOOLEAN; -// } -// -// if (tocheck_type != Type.BOOLEAN) { -// System.out.println("While loop condition wrong type should be bool, but was:"+tocheck_type + "and got thi node"+toCheck); -// } -// HashMap localTable = new HashMap<>(); -// scopes.add(localTable); -// visit(node.getBlock()); -// toCheck = visit(node.getExpression().getNode()); -// scopes.remove(localTable); -// -// } -} diff --git a/test.carl b/test.carl index 3c7842c..dcfe604 100644 --- a/test.carl +++ b/test.carl @@ -1 +1,14 @@ var number:int = 20 + +var difficulty:int = 20 + +var Goblin : enemy ={ + var difficulty : int = 1 + var health : int = 500 + var symbol : string= "O" +} +var Goblin : enemy ={ + var difficulty : int = 1 + var health : int = 500 + var symbol : string= "O" +} \ No newline at end of file From 87b558c78a58c42f2807e3c390d28c9b86c8015c Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sat, 4 May 2024 21:43:03 +0200 Subject: [PATCH 43/94] sdasd --- test.carl | 1 + 1 file changed, 1 insertion(+) diff --git a/test.carl b/test.carl index dcfe604..9149b0d 100644 --- a/test.carl +++ b/test.carl @@ -6,6 +6,7 @@ var Goblin : enemy ={ var difficulty : int = 1 var health : int = 500 var symbol : string= "O" + var difficulty:int = 20 } var Goblin : enemy ={ var difficulty : int = 1 From 266521ca40a293ba0bbeb6825ea7efa99c22f98a Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sat, 4 May 2024 23:07:22 +0200 Subject: [PATCH 44/94] Array declaration virker --- .../carl/Semantic_A/TypeChecker.java | 108 ++++++++++++++++-- test.carl | 19 ++- 2 files changed, 108 insertions(+), 19 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 480b063..319cd2e 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -12,7 +12,7 @@ public class TypeChecker { "generateCorridors", "generateSpawns", "printMap", "generatePrint", "writeToFile", "overlap", "tileInformationStringBuilder", "setSeed")); HashMap> strucvariablesTable; - HashMap structTypes; + HashMap structTypes; // HashMap fTable; // function table, // identifier(x) og node @@ -24,6 +24,7 @@ public class TypeChecker { Boolean hasReturnStatement = false; String currentActiveFunction = ""; public Boolean thereWasAnError = false; + String currentIdentifierCheck = ""; public TypeChecker() { @@ -40,6 +41,7 @@ public TypeChecker() { } public void visitor(AstNode node) { + System.out.println(node); if (node instanceof ProgramNode) { visitProgramNode((ProgramNode) node); } @@ -83,6 +85,12 @@ public void visitStatements(StatementNode node) { if (node.getNode() instanceof StructureDefinitionNode) { visitStruct((StructureDefinitionNode) node.getNode()); } + if (node.getNode() instanceof ArrayDefinitionNode) { + visistarrayDekleration((ArrayDefinitionNode) node.getNode()); + } + if (node.getNode() instanceof ArrayAssignmentNode) { + visistArrayAssignment((ArrayAssignmentNode) node.getNode()); + } } public void errorHandler(String errorMessage) { @@ -92,6 +100,90 @@ public void errorHandler(String errorMessage) { System.err.println(errorMessage); } + /* + * VI skal hente værdi fra table + * Tjekke alle argumenter + * tjekke højre side + * tjekke for existens + */ + public void visistArrayAssignment(ArrayAssignmentNode node) { + String identifier = node.getIdentifier().toString(); + Boolean found =false; + if (!found) { + Type arrayType = scopes.getLast().get(identifier); + + + Boolean validTypes = true; + Type sizeType = Type.UNKNOWN; + int arguementNumber = 0; + List sizes = node.getSizes(); + for (int i = 0; i < sizes.size(); i++) { + AstNode astNode = sizes.get(i); + sizeType = getType(astNode); + if (sizeType != arrayType) { + arguementNumber = i; + validTypes = false; + + break; + } + } + if (validTypes) { + scopes.getLast().put(identifier, arrayType); + } else { + errorHandler("Tried to declare the array:" + identifier + " but argument: " + arguementNumber + + " is of type:" + sizeType + " and should be:" + arrayType); + } + + } else { + errorHandler("Identifier:" + identifier + " is alredy used, rename it"); + } + } + + /* + * Vi skal hente den dekleerede type + * VI skal tjekke om den eksistere + * vi skal tjekke om alle argumenterne er valide. + */ + public void visistarrayDekleration(ArrayDefinitionNode node) { + + String identifier = node.getIdentifier().toString(); + boolean found = scopes.getFirst().containsKey(identifier); + + for (int i = activeScope.getLast(); i < scopes.size(); i++) { + if (scopes.get(i).containsKey(identifier)) { + found = true; + } + } + if (!found) { + Type arrayType = getType(node.getType()); + + Boolean validTypes = true; + Type sizeType = Type.UNKNOWN; + int arguementNumber = 0; + List sizes = node.getSizes(); + for (int i = 0; i < sizes.size(); i++) { + AstNode astNode = sizes.get(i); + sizeType = getType(astNode); + if (sizeType != arrayType) { + arguementNumber = i; + validTypes = false; + + break; + } + } + if (validTypes) { + scopes.getLast().put(identifier, arrayType); + } else { + errorHandler("Tried to declare the array:" + identifier + " but argument: " + arguementNumber + + " is of type:" + sizeType + " and should be:" + arrayType); + } + + } else { + errorHandler("Identifier:" + identifier + " is alredy used, rename it"); + } + + } + public Type relationOperatorTypeCheck(RelationsAndLogicalOperatorNode node) { AstNode left = node.getLeft(); @@ -176,11 +268,14 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { } public Type getVariable(IdentifierNode node) { + if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { + currentIdentifierCheck = node.getIdentifier().toString(); return scopes.getFirst().get(node.getIdentifier().toString()); } for (int i = activeScope.getLast(); i < scopes.size(); i++) { if (scopes.get(i).containsKey(node.getIdentifier().toString())) { + currentIdentifierCheck = node.getIdentifier().toString(); return scopes.get(i).get(node.getIdentifier().toString()); } } @@ -373,11 +468,10 @@ public void visitFunctionCall(FunctionCallNode node) { */ public void visitStruct(StructureDefinitionNode node) { String identifier = node.getIdentifier().toString(); - System.out.println("structtypes"+structTypes); + System.out.println("structtypes" + structTypes); if (!strucvariablesTable.containsKey(identifier)) { - - - Type structType =getType(node.getType()); + + Type structType = getType(node.getType()); HashMap localETable = new HashMap<>(); @@ -390,7 +484,7 @@ public void visitStruct(StructureDefinitionNode node) { structTypes.put(identifier, structType); strucvariablesTable.put(identifier, localETable); scopes.remove(localETable); - + } else { errorHandler("Struct " + node.getIdentifier().toString() + " already exists"); } @@ -459,7 +553,7 @@ public Type getType(Object node) { } else if (node instanceof BoolNode) { type = Type.BOOLEAN; } else if (node instanceof ExpressionNode) { - + type = getType(((ExpressionNode) node).getNode()); } else if (node instanceof StringNode) { type = Type.STRING; } else if (node instanceof TypeNode) { diff --git a/test.carl b/test.carl index 9149b0d..7be9b22 100644 --- a/test.carl +++ b/test.carl @@ -1,15 +1,10 @@ var number:int = 20 - +var haha:string = "hej" var difficulty:int = 20 -var Goblin : enemy ={ - var difficulty : int = 1 - var health : int = 500 - var symbol : string= "O" - var difficulty:int = 20 -} -var Goblin : enemy ={ - var difficulty : int = 1 - var health : int = 500 - var symbol : string= "O" -} \ No newline at end of file +var array: int[3][3] + + +array[1][2] = 71 + +//var x: int = array[1][2] \ No newline at end of file From 1ce0fd52675b1c79e052557f9078fd029fb099e4 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sat, 4 May 2024 23:17:06 +0200 Subject: [PATCH 45/94] Assigment af array bliver nu tjekket --- .../carl/Semantic_A/TypeChecker.java | 28 +++++++++++-------- test.carl | 2 +- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 319cd2e..f23d592 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -101,39 +101,45 @@ public void errorHandler(String errorMessage) { } /* - * VI skal hente værdi fra table + * VI skal hente Type fra table * Tjekke alle argumenter * tjekke højre side * tjekke for existens */ public void visistArrayAssignment(ArrayAssignmentNode node) { String identifier = node.getIdentifier().toString(); - Boolean found =false; + Boolean found = false; if (!found) { Type arrayType = scopes.getLast().get(identifier); - - Boolean validTypes = true; + Boolean validTypesaccesTypes = true; Type sizeType = Type.UNKNOWN; int arguementNumber = 0; - List sizes = node.getSizes(); + Type allowedAccesTypesForArrays = Type.INT; + + List sizes = node.getIndices(); for (int i = 0; i < sizes.size(); i++) { AstNode astNode = sizes.get(i); sizeType = getType(astNode); - if (sizeType != arrayType) { + if (sizeType != allowedAccesTypesForArrays) { arguementNumber = i; - validTypes = false; + validTypesaccesTypes = false; break; } } - if (validTypes) { - scopes.getLast().put(identifier, arrayType); - } else { - errorHandler("Tried to declare the array:" + identifier + " but argument: " + arguementNumber + if (!validTypesaccesTypes) { + errorHandler("Tried to assign the array:" + identifier + " but acces value: " + arguementNumber + " is of type:" + sizeType + " and should be:" + arrayType); } + // Tjek venstre mod højre + Type assignType = getType(node.getValue()); + if (arrayType != assignType) { + errorHandler("Tried to assign the type:" + assignType + " to the array:" + identifier + + " that has the type:" + arrayType + ", and that is ilegal"); + } + } else { errorHandler("Identifier:" + identifier + " is alredy used, rename it"); } diff --git a/test.carl b/test.carl index 7be9b22..39037e7 100644 --- a/test.carl +++ b/test.carl @@ -5,6 +5,6 @@ var difficulty:int = 20 var array: int[3][3] -array[1][2] = 71 +array[1]["hej"] = "hej" //var x: int = array[1][2] \ No newline at end of file From 856557aafb05d82b5aaab000ddcd3958d869f866 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sat, 4 May 2024 23:36:52 +0200 Subject: [PATCH 46/94] Array acces virker nu og typen bliver resovlet --- .../carl/Semantic_A/TypeChecker.java | 48 +++++++++++++++++++ test.carl | 4 +- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index f23d592..70b9e82 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -91,6 +91,7 @@ public void visitStatements(StatementNode node) { if (node.getNode() instanceof ArrayAssignmentNode) { visistArrayAssignment((ArrayAssignmentNode) node.getNode()); } + } public void errorHandler(String errorMessage) { @@ -100,6 +101,41 @@ public void errorHandler(String errorMessage) { System.err.println(errorMessage); } + /* + * Vi skal tjekke om den er ordenligt skrevet og retunere en type? + */ + public void visistArrayAccesNodeFn(ArrayAccessNode node) { + String identifier = node.getIdentifier().toString(); + boolean found = scopes.getFirst().containsKey(identifier); + + for (int i = activeScope.getLast(); i < scopes.size(); i++) { + if (scopes.get(i).containsKey(identifier)) { + found = true; + } + } + if (found) { + Type allowedAccesTypesForArrays = Type.INT; + Boolean validTypesaccesTypes = true; + Type sizeType = Type.UNKNOWN; + int arguementNumber = 0; + + List sizes = node.getIndices(); + for (int i = 0; i < sizes.size(); i++) { + AstNode astNode = sizes.get(i); + sizeType = getType(astNode); + if (sizeType != allowedAccesTypesForArrays) { + arguementNumber = i; + errorHandler("Tried to assign the array:" + identifier + " but acces value: " + arguementNumber + + " is of type:" + sizeType + " and should be INT"); + validTypesaccesTypes = false; + + break; + } + } + + } + } + /* * VI skal hente Type fra table * Tjekke alle argumenter @@ -109,6 +145,13 @@ public void errorHandler(String errorMessage) { public void visistArrayAssignment(ArrayAssignmentNode node) { String identifier = node.getIdentifier().toString(); Boolean found = false; + found = scopes.getFirst().containsKey(identifier); + + for (int i = activeScope.getLast(); i < scopes.size(); i++) { + if (scopes.get(i).containsKey(identifier)) { + found = true; + } + } if (!found) { Type arrayType = scopes.getLast().get(identifier); @@ -545,6 +588,11 @@ public Type getType(Object node) { type = getVariable((IdentifierNode) node); // Vis x giv mig x value } + } else if (node instanceof ArrayAccessNode) { + + visistArrayAccesNodeFn(((ArrayAccessNode) node)); + + type = getType(((ArrayAccessNode) node).getIdentifier()); } else if (node instanceof BinaryOperatorNode) { type = binaryOperatorTypeCheck((BinaryOperatorNode) node); } else if (node instanceof RelationsAndLogicalOperatorNode) { diff --git a/test.carl b/test.carl index 39037e7..60e5da9 100644 --- a/test.carl +++ b/test.carl @@ -5,6 +5,6 @@ var difficulty:int = 20 var array: int[3][3] -array[1]["hej"] = "hej" -//var x: int = array[1][2] \ No newline at end of file + +var x: int = array[2][2] \ No newline at end of file From 6320f46b8e725f6100287f8286dbf6ae299bbb0b Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sat, 4 May 2024 23:49:52 +0200 Subject: [PATCH 47/94] Yes --- src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java | 3 +-- .../carl/Semantic_A/TypeChecker.java | 3 --- test.carl | 15 +++++++++------ 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index 2cd6206..40db5a6 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -46,10 +46,9 @@ public static void main(String... args) { TypeChecker typeChecker = new TypeChecker(); typeChecker.visitor(astRoot); - System.out.println("error"); + if (!typeChecker.thereWasAnError) { Interpreter inter = new Interpreter(); - System.out.println("no error"); inter.visit(astRoot); } // Interpreter is a class that can traverse the AST and interpret or execute the diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 70b9e82..0ca5d5f 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -13,9 +13,6 @@ public class TypeChecker { "tileInformationStringBuilder", "setSeed")); HashMap> strucvariablesTable; HashMap structTypes; - // HashMap fTable; // function table, - // identifier(x) og node - HashMap eTable;// variable table, identifier(x) og node(int) Stack> scopes; // scope table, variable identifier(x) og node Deque activeScope;// Hvilket scope vi er i nu diff --git a/test.carl b/test.carl index 60e5da9..2c2fe94 100644 --- a/test.carl +++ b/test.carl @@ -1,10 +1,13 @@ var number:int = 20 -var haha:string = "hej" -var difficulty:int = 20 - -var array: int[3][3] - +var difficulty:int = 20 +var Goblin : enemy ={ + var difficulty : int = 1 + var health : int = 500 + var symbol : string= "O" + // var difficulty:int = 20 +} -var x: int = array[2][2] \ No newline at end of file +//var number2:int = Goblin.size() +//Goblin.health =20 \ No newline at end of file From 108cbc15c5050a79ba1c5a225e184c99488337d6 Mon Sep 17 00:00:00 2001 From: MShadiF Date: Sun, 5 May 2024 16:20:55 +0200 Subject: [PATCH 48/94] Propertyaccess and propertyassignment done --- .../carl/Semantic_A/TypeChecker.java | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 0ca5d5f..3c09d00 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -88,7 +88,12 @@ public void visitStatements(StatementNode node) { if (node.getNode() instanceof ArrayAssignmentNode) { visistArrayAssignment((ArrayAssignmentNode) node.getNode()); } - + if (node.getNode() instanceof PropertyAssignmentNode) { + visitPropertyAssignment((PropertyAssignmentNode) node.getNode()); + } + if (node.getNode() instanceof MethodCallNode) { + visitMethodCall((MethodCallNode) node.getNode()); + } } public void errorHandler(String errorMessage) { @@ -230,6 +235,53 @@ public void visistarrayDekleration(ArrayDefinitionNode node) { } + public void visitPropertyAssignment(PropertyAssignmentNode node) { + Type oldType = visitPropertyAccessNode(node.getPropertyAccessNode()); + Type newType = getType(node.getValue()); + errorHandler(oldType + " " + newType); + if (oldType != newType) { + errorHandler("Type " + oldType + " does not match " + newType); + } + } + + //Ved ikke om den virker endnu, kan være det er forkert + public Type visitPropertyAccessNode(PropertyAccessNode node) { + List validPropertyAccess = new ArrayList<>(Arrays.asList("size", "get")); + //Viker ikke til det her behøves at tjekkes +// Type structType = getType(node.getList()); +// System.out.println(structType); +// +// if (!structTypes.containsValue(structType)) { +// errorHandler("could not find the struct type: " + structType); +// return Type.UNKNOWN; +// } + + String firstIdentifier = node.getIdentifiers().get(0).toString(); + if (!strucvariablesTable.containsKey(firstIdentifier)) { + errorHandler("could not find the struct variable: " + firstIdentifier); + } + + HashMap listOfIdentifiers = strucvariablesTable.get(firstIdentifier); + + + + if (!validPropertyAccess.contains(firstIdentifier) && node.getIdentifiers().size() <= 1 || !listOfIdentifiers.containsKey(node.getIdentifiers().get(1).toString())) { + errorHandler("you need 3 arguments"); + } + + if (strucvariablesTable.containsKey(firstIdentifier) && node.getIdentifiers().size() >= 2 && listOfIdentifiers.containsKey(node.getIdentifiers().get(1).toString())) { + Type identifierType = listOfIdentifiers.get(node.getIdentifiers().get(1).toString()); + return getType(identifierType.getTypeName()); + } + return Type.UNKNOWN; + } + + public void visitMethodCall(MethodCallNode node) { + System.out.println("ekjrgnekrjgkewrjg"); + Type type = visitPropertyAccessNode(node.getPropertyAccessContext()); + System.out.println(type); + } + public Type relationOperatorTypeCheck(RelationsAndLogicalOperatorNode node) { AstNode left = node.getLeft(); @@ -586,10 +638,11 @@ public Type getType(Object node) { } } else if (node instanceof ArrayAccessNode) { - visistArrayAccesNodeFn(((ArrayAccessNode) node)); type = getType(((ArrayAccessNode) node).getIdentifier()); + } else if (node instanceof PropertyAccessNode) { + type = visitPropertyAccessNode((PropertyAccessNode) node); } else if (node instanceof BinaryOperatorNode) { type = binaryOperatorTypeCheck((BinaryOperatorNode) node); } else if (node instanceof RelationsAndLogicalOperatorNode) { From 32301c8e112b8dfd7b2e88003150280f1e9ed9a3 Mon Sep 17 00:00:00 2001 From: MShadiF Date: Mon, 6 May 2024 20:30:41 +0200 Subject: [PATCH 49/94] Update TypeChecker.java --- .../carl/Semantic_A/TypeChecker.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 3c09d00..d15d5c1 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -4,6 +4,8 @@ import java.util.*; +import static java.lang.Integer.parseInt; + public class TypeChecker { HashMap typeOfReturnFunction; @@ -11,7 +13,7 @@ public class TypeChecker { List listOfInbuiltFunctions = new ArrayList<>(Arrays.asList("print", "generateGrid", "generateRooms", "generateCorridors", "generateSpawns", "printMap", "generatePrint", "writeToFile", "overlap", "tileInformationStringBuilder", "setSeed")); - HashMap> strucvariablesTable; + HashMap> structVariablesTable; HashMap structTypes; HashMap eTable;// variable table, identifier(x) og node(int) Stack> scopes; // scope table, variable identifier(x) og node @@ -33,7 +35,7 @@ public TypeChecker() { scopes.add(eTable); typeOfReturnFunction = new HashMap<>(); functionParameters = new HashMap<>(); - strucvariablesTable = new HashMap<>(); + structVariablesTable = new HashMap<>(); structTypes = new HashMap<>(); } @@ -76,7 +78,6 @@ public void visitStatements(StatementNode node) { } if (node.getNode() instanceof ReturnStatementNode) { hasReturnStatement = true; - System.out.println("we get in return statement" + hasReturnStatement); visitReturnNode((ReturnStatementNode) node.getNode()); } if (node.getNode() instanceof StructureDefinitionNode) { @@ -92,6 +93,7 @@ public void visitStatements(StatementNode node) { visitPropertyAssignment((PropertyAssignmentNode) node.getNode()); } if (node.getNode() instanceof MethodCallNode) { + errorHandler("ewjrngkewgjewkejnweklrglewrkngewkrgkwen"); visitMethodCall((MethodCallNode) node.getNode()); } } @@ -257,11 +259,11 @@ public Type visitPropertyAccessNode(PropertyAccessNode node) { // } String firstIdentifier = node.getIdentifiers().get(0).toString(); - if (!strucvariablesTable.containsKey(firstIdentifier)) { + if (!structVariablesTable.containsKey(firstIdentifier) && !validPropertyAccess.contains(firstIdentifier)) { errorHandler("could not find the struct variable: " + firstIdentifier); } - HashMap listOfIdentifiers = strucvariablesTable.get(firstIdentifier); + HashMap listOfIdentifiers = structVariablesTable.get(firstIdentifier); @@ -269,7 +271,7 @@ public Type visitPropertyAccessNode(PropertyAccessNode node) { errorHandler("you need 3 arguments"); } - if (strucvariablesTable.containsKey(firstIdentifier) && node.getIdentifiers().size() >= 2 && listOfIdentifiers.containsKey(node.getIdentifiers().get(1).toString())) { + if (structVariablesTable.containsKey(firstIdentifier) && node.getIdentifiers().size() >= 2 && listOfIdentifiers.containsKey(node.getIdentifiers().get(1).toString())) { Type identifierType = listOfIdentifiers.get(node.getIdentifiers().get(1).toString()); return getType(identifierType.getTypeName()); } @@ -277,9 +279,13 @@ public Type visitPropertyAccessNode(PropertyAccessNode node) { } public void visitMethodCall(MethodCallNode node) { - System.out.println("ekjrgnekrjgkewrjg"); - Type type = visitPropertyAccessNode(node.getPropertyAccessContext()); - System.out.println(type); + List names = new ArrayList<>(structTypes.keySet()); + try { + int i = Integer.parseInt(node.getValue().toString()); + System.out.println("Parsed integer value: " + i); + } catch (NumberFormatException e) { + System.err.println("Error parsing integer: " + e.getMessage()); + } } public Type relationOperatorTypeCheck(RelationsAndLogicalOperatorNode node) { @@ -566,8 +572,7 @@ public void visitFunctionCall(FunctionCallNode node) { */ public void visitStruct(StructureDefinitionNode node) { String identifier = node.getIdentifier().toString(); - System.out.println("structtypes" + structTypes); - if (!strucvariablesTable.containsKey(identifier)) { + if (!structVariablesTable.containsKey(identifier)) { Type structType = getType(node.getType()); @@ -580,13 +585,12 @@ public void visitStruct(StructureDefinitionNode node) { visitVariableDeclarationforStructs(declaration); } structTypes.put(identifier, structType); - strucvariablesTable.put(identifier, localETable); + structVariablesTable.put(identifier, localETable); scopes.remove(localETable); } else { errorHandler("Struct " + node.getIdentifier().toString() + " already exists"); } - System.out.println(strucvariablesTable); } private void visitVariableDeclarationforStructs(VariableDeclarationNode node) { @@ -643,6 +647,8 @@ public Type getType(Object node) { type = getType(((ArrayAccessNode) node).getIdentifier()); } else if (node instanceof PropertyAccessNode) { type = visitPropertyAccessNode((PropertyAccessNode) node); + } else if (node instanceof MethodCallNode) { + visitMethodCall((MethodCallNode) node); } else if (node instanceof BinaryOperatorNode) { type = binaryOperatorTypeCheck((BinaryOperatorNode) node); } else if (node instanceof RelationsAndLogicalOperatorNode) { From 51c45680a09993c709ead85043d657d05ad97775 Mon Sep 17 00:00:00 2001 From: MShadiF Date: Mon, 6 May 2024 21:36:34 +0200 Subject: [PATCH 50/94] =?UTF-8?q?Test=20p=C3=A5=20if=20og=20while=20i=20ty?= =?UTF-8?q?pechecker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carl/Semantic_A/TypeCheckerTest.java | 52 ++++++++++++++----- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index a2477a7..8c30083 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -8,7 +8,10 @@ import java.io.InputStream; import java.io.PrintStream; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; @@ -18,14 +21,6 @@ import dk.aau.cs_24_sw_4_16.carl.CARLLexer; import dk.aau.cs_24_sw_4_16.carl.CARLParser; -import dk.aau.cs_24_sw_4_16.carl.CstToAst.AstNode; -import dk.aau.cs_24_sw_4_16.carl.CstToAst.BinaryOperatorNode; -import dk.aau.cs_24_sw_4_16.carl.CstToAst.BoolNode; -import dk.aau.cs_24_sw_4_16.carl.CstToAst.CstToAstVisitor; -import dk.aau.cs_24_sw_4_16.carl.CstToAst.FloatNode; -import dk.aau.cs_24_sw_4_16.carl.CstToAst.IntNode; -import dk.aau.cs_24_sw_4_16.carl.CstToAst.RelationsAndLogicalOperatorNode; -import dk.aau.cs_24_sw_4_16.carl.CstToAst.StringNode; public class TypeCheckerTest { @@ -161,31 +156,62 @@ void testVisitFunctionDefinition() { @Test void testVisitIfStatement() { + List expressionNodeList = new ArrayList<>(); + expressionNodeList.add(new ExpressionNode(new BoolNode("true"))); + expressionNodeList.add(new ExpressionNode(new BoolNode("false"))); + List blockNodeList = new ArrayList<>(); + blockNodeList.add(new BlockNode()); + blockNodeList.add(new BlockNode()); + + IfStatementNode node1 = new IfStatementNode(blockNodeList, expressionNodeList); + typeChecker.visitIfStatement(node1); + Type correctType1 = typeChecker.getType(expressionNodeList.get(0)); + Type correctType2 = typeChecker.getType(expressionNodeList.get(1)); + assertEquals(Type.BOOLEAN, correctType1); + assertEquals(Type.BOOLEAN, correctType2); + + + expressionNodeList.add(new ExpressionNode(new IntNode("2"))); + blockNodeList.add(new BlockNode()); + IfStatementNode node2 = new IfStatementNode(blockNodeList, expressionNodeList); + typeChecker.visitIfStatement(node2); + Type errorType = typeChecker.getType(expressionNodeList.get(2)); + assertEquals(Type.INT, errorType, "If statements expression must resolve to bool expression, and this resolve to Type:INT"); } @Test - void testVisitProgramNode() { + void testVisitWhileLoop() { + ExpressionNode expressionNode1 = new ExpressionNode(new BoolNode("true")); + BlockNode blockNode = new BlockNode(); + + typeChecker.visitWhileLoop(new WhileLoopNode(expressionNode1, blockNode)); + Type correctType = typeChecker.getType(expressionNode1); + assertEquals(Type.BOOLEAN, correctType); + ExpressionNode expressionNode2 = new ExpressionNode(new StringNode("hello")); + Type errorType = typeChecker.getType(expressionNode2); + typeChecker.visitWhileLoop(new WhileLoopNode(expressionNode2, blockNode)); + assertEquals(Type.STRING, errorType, "While loop expresion must resolve to bool expresion, and this resolve to Type:" + errorType); } @Test - void testVisitReturnNode() { + void testVisitProgramNode() { } @Test - void testVisitStatements() { + void testVisitReturnNode() { } @Test - void testVisitStruct() { + void testVisitStatements() { } @Test - void testVisitWhileLoop() { + void testVisitStruct() { } From 1fea590a17af27ca88a89b71c8e89f15123f1747 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Thu, 9 May 2024 14:55:41 +0200 Subject: [PATCH 51/94] god start og lille bug fix --- .../carl/Semantic_A/TypeChecker.java | 48 ++-- .../carl/Semantic_A/TypeCheckerTest.java | 234 +++++++++++++++++- 2 files changed, 259 insertions(+), 23 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index d15d5c1..7b632fe 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -246,17 +246,17 @@ public void visitPropertyAssignment(PropertyAssignmentNode node) { } } - //Ved ikke om den virker endnu, kan være det er forkert + // Ved ikke om den virker endnu, kan være det er forkert public Type visitPropertyAccessNode(PropertyAccessNode node) { List validPropertyAccess = new ArrayList<>(Arrays.asList("size", "get")); - //Viker ikke til det her behøves at tjekkes -// Type structType = getType(node.getList()); -// System.out.println(structType); -// -// if (!structTypes.containsValue(structType)) { -// errorHandler("could not find the struct type: " + structType); -// return Type.UNKNOWN; -// } + // Viker ikke til det her behøves at tjekkes + // Type structType = getType(node.getList()); + // System.out.println(structType); + // + // if (!structTypes.containsValue(structType)) { + // errorHandler("could not find the struct type: " + structType); + // return Type.UNKNOWN; + // } String firstIdentifier = node.getIdentifiers().get(0).toString(); if (!structVariablesTable.containsKey(firstIdentifier) && !validPropertyAccess.contains(firstIdentifier)) { @@ -265,13 +265,13 @@ public Type visitPropertyAccessNode(PropertyAccessNode node) { HashMap listOfIdentifiers = structVariablesTable.get(firstIdentifier); - - - if (!validPropertyAccess.contains(firstIdentifier) && node.getIdentifiers().size() <= 1 || !listOfIdentifiers.containsKey(node.getIdentifiers().get(1).toString())) { + if (!validPropertyAccess.contains(firstIdentifier) && node.getIdentifiers().size() <= 1 + || !listOfIdentifiers.containsKey(node.getIdentifiers().get(1).toString())) { errorHandler("you need 3 arguments"); } - if (structVariablesTable.containsKey(firstIdentifier) && node.getIdentifiers().size() >= 2 && listOfIdentifiers.containsKey(node.getIdentifiers().get(1).toString())) { + if (structVariablesTable.containsKey(firstIdentifier) && node.getIdentifiers().size() >= 2 + && listOfIdentifiers.containsKey(node.getIdentifiers().get(1).toString())) { Type identifierType = listOfIdentifiers.get(node.getIdentifiers().get(1).toString()); return getType(identifierType.getTypeName()); } @@ -383,20 +383,28 @@ public Type getVariable(IdentifierNode node) { return scopes.get(i).get(node.getIdentifier().toString()); } } - throw new RuntimeException("could not find the variable " + node.getIdentifier()); + errorHandler("could not find the variable " + node.getIdentifier()); + // throw new RuntimeException("could not find the variable " + + // node.getIdentifier()); + return Type.UNKNOWN; } // Check if return = type er det samme som den function den står i. public void visitReturnNode(ReturnStatementNode node) { Type returnType = getType(node.getReturnValue()); - Type activeFunction = typeOfReturnFunction.get(currentActiveFunction); - if (Objects.equals(currentActiveFunction, "")) { + if (currentActiveFunction == "") { errorHandler("You have made return statement outside a function THAT IS illigal"); + } else { + Type activeFunction = typeOfReturnFunction.get(currentActiveFunction); + if (Objects.equals(currentActiveFunction, "")) { + errorHandler("You have made return statement outside a function THAT IS illigal"); + } + if (returnType != activeFunction) { + errorHandler("The return type " + returnType + " Does not match the return statement of the function " + + activeFunction.getTypeName()); + } } - if (returnType != activeFunction) { - errorHandler("The return type " + returnType + " Does not match the return statement of the function " - + activeFunction.getTypeName()); - } + } public void visitAssignNode(AssignmentNode node) { diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index 8c30083..2a5e0ba 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -1,6 +1,7 @@ package dk.aau.cs_24_sw_4_16.carl.Semantic_A; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -171,13 +172,13 @@ void testVisitIfStatement() { assertEquals(Type.BOOLEAN, correctType1); assertEquals(Type.BOOLEAN, correctType2); - expressionNodeList.add(new ExpressionNode(new IntNode("2"))); blockNodeList.add(new BlockNode()); IfStatementNode node2 = new IfStatementNode(blockNodeList, expressionNodeList); typeChecker.visitIfStatement(node2); Type errorType = typeChecker.getType(expressionNodeList.get(2)); - assertEquals(Type.INT, errorType, "If statements expression must resolve to bool expression, and this resolve to Type:INT"); + assertEquals(Type.INT, errorType, + "If statements expression must resolve to bool expression, and this resolve to Type:INT"); } @Test @@ -192,7 +193,8 @@ void testVisitWhileLoop() { ExpressionNode expressionNode2 = new ExpressionNode(new StringNode("hello")); Type errorType = typeChecker.getType(expressionNode2); typeChecker.visitWhileLoop(new WhileLoopNode(expressionNode2, blockNode)); - assertEquals(Type.STRING, errorType, "While loop expresion must resolve to bool expresion, and this resolve to Type:" + errorType); + assertEquals(Type.STRING, errorType, + "While loop expresion must resolve to bool expresion, and this resolve to Type:" + errorType); } @Test @@ -219,4 +221,230 @@ void testVisitStruct() { void testVisitor() { } + + @Test + void testTypeCheker1() { + /* + * Tried to assign the array:" + identifier + " but acces value: " + + * arguementNumber + * + " is of type:" + sizeType + " and should be INT + */ + } + + @Test + void testTypeCheker2() { + /* + * Tried to assign the array:" + identifier + " but acces value: " + + * arguementNumber + * + " is of type:" + sizeType + " and should be:" + arrayType + */ + } + + @Test + void testTypeCheker3() { + /* + * Tried to assign the type:" + assignType + " to the array:" + identifier + * + " that has the type:" + arrayType + ", and that is ilegal + */ + } + + @Test + void testTypeCheker4() { + /* + * Identifier:" + identifier + " is alredy used, rename it + */ + } + + @Test + void testTypeCheker5() { + /* + * Tried to declare the array:" + identifier + " but argument: " + + * arguementNumber + * + " is of type:" + sizeType + " and should be:" + arrayType + */ + } + + @Test + void testTypeCheker6() { + /* + * Identifier:" + identifier + " is alredy used, rename it + */ + } + + @Test + void testTypeCheker7() { + /* + * Type " + oldType + " does not match " + newType + * + */ + } + + @Test + void testTypeCheker8() { + /* + * "Wrong types for binary operation:" + leftType + ":" + left + " And:" + right + * + ":" + rightType + */ + } + + @Test + void testTypeCheker9() { + /* + * "Wrong types for relation operation:" + leftType + ":" + left + " And:" + + * right + ":" + rightType + */ + } + + @Test + void testTypeCheker10() { + /* + * "Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + * + " that has the type:" + variableType + * + " And that is hella iligal" + */ + } + + public String normalizeOutput() { + String normalizedActualOutput = errContent.toString().trim().replace("\r\n", "\n").replace("\r", "\n"); + return normalizedActualOutput; + } + + @Test + void testTypeCheker11() { + /* + * Variable declaration rigtig type. + */ + String code = """ + var test_variable:int = 20 + var test_variable2:string=test_variable + """; + AstNode astTree = treemaker(code); + + String correct_error = """ + Error 1 + Tryied to asssign Type:INT to the variable:test_variable2 that has the type:STRING And that is hella iligal"""; + typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + assertEquals(correct_error.trim(), terminal_Errors); + + } + + @Test + void testTypeCheker12() { + /* + * Må ikke deklere variable i samme scope. + */ + + String code = """ + var test_variable:int = 20 + var test_variable:int =40 + """; + AstNode astTree = treemaker(code); + + String correct_error = """ + Error 1 + variable test_variable already exists"""; + typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + assertEquals(correct_error.trim(), terminal_Errors); + } + + @Test + void testTypeCheker13() { + /* + * Try to use variable that does not exist + * Vi får flere fejl, men den først fejl burde være could not found variable + */ + + String code = """ + var test_variable:int = 20 + test_variable=y + """; + AstNode astTree = treemaker(code); + + String correct_error = """ + Error 1 + could not find the variable y"""; + typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + // assertEquals(correct_error.trim(), terminal_Errors); + assertTrue(terminal_Errors.contains(correct_error)); + } + + @Test + void testTypeCheker14() { + /* + * Giver fejl vis return er ude for function + */ + String code = """ + var variable:int =20 + return 10 + """; + AstNode astTree = treemaker(code); + + String correct_error = """ + Error 1 + You have made return statement outside a function THAT IS illigal"""; + typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + assertEquals(correct_error.trim(), terminal_Errors); + // assertTrue( terminal_Errors.contains(correct_error)); + } + + @Test + void testTypeCheker15() { + /* + * Giver ikke fejl vis return er inde i en funktion + */ + String code = """ + var variable:int =4 + var y:int =3 + var x:int =6 + fn plus (y:int)-> int{ + return y+x + } + + """; + AstNode astTree = treemaker(code); + + String correct_error = ""; + typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + assertEquals(correct_error.trim(), terminal_Errors); + // assertTrue( terminal_Errors.contains(correct_error)); + } + + @Test + void testTypeCheker16() { + /* + * Tester at den smider fejl vis man prøver at retunere den forkerte type. + */ + String code = """ + var variable:int =4 + var y:int =3 + var x:int =6 + fn plus (y:int)-> int{ + var variable_string:string="hej" + return variable_string + } + + """; + AstNode astTree = treemaker(code); + + String correct_error = """ + Error 1 +The return type STRING Does not match the return statement of the function int + """; + typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + assertEquals(correct_error.trim(), terminal_Errors); + // assertTrue( terminal_Errors.contains(correct_error)); + } + + @Test + void testTypeCheker17() { + /* + * + */ + } } From 8c450442c29170ede11515489b560dc3d0f2c015 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Thu, 9 May 2024 15:23:52 +0200 Subject: [PATCH 52/94] cst to ast fejler? --- .../carl/Semantic_A/TypeChecker.java | 1 + .../carl/Semantic_A/TypeCheckerTest.java | 87 ++++++++++++------- .../carl/Semantic_A/typechecker_test.md | 42 +++++++++ 3 files changed, 98 insertions(+), 32 deletions(-) create mode 100644 src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 7b632fe..c2069ba 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -545,6 +545,7 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { * Vi skal sige hvis arguemtnet er en forkert type. */ public void visitFunctionCall(FunctionCallNode node) { + System.out.println("we get in here"); if (!listOfInbuiltFunctions.contains(node.getFunctionName().toString())) { HashMap localETable = new HashMap<>(); scopes.add(localETable); diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index 2a5e0ba..c7f4cc1 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -394,24 +394,24 @@ void testTypeCheker14() { @Test void testTypeCheker15() { /* - * Giver ikke fejl vis return er inde i en funktion + * Giver ikke fejl vis return er inde i en funktion */ String code = """ - var variable:int =4 - var y:int =3 - var x:int =6 - fn plus (y:int)-> int{ - return y+x - } + var variable:int =4 + var y:int =3 + var x:int =6 + fn plus (y:int)-> int{ + return y+x + } - """; - AstNode astTree = treemaker(code); + """; + AstNode astTree = treemaker(code); - String correct_error = ""; - typeChecker.visitor(astTree); - String terminal_Errors = normalizeOutput(); - assertEquals(correct_error.trim(), terminal_Errors); - // assertTrue( terminal_Errors.contains(correct_error)); + String correct_error = ""; + typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + assertEquals(correct_error.trim(), terminal_Errors); + // assertTrue( terminal_Errors.contains(correct_error)); } @Test @@ -420,31 +420,54 @@ void testTypeCheker16() { * Tester at den smider fejl vis man prøver at retunere den forkerte type. */ String code = """ - var variable:int =4 - var y:int =3 - var x:int =6 - fn plus (y:int)-> int{ - var variable_string:string="hej" - return variable_string - } + var variable:int =4 + var y:int =3 + var x:int =6 + fn plus (y:int)-> int{ + var variable_string:string="hej" + return variable_string + } - """; - AstNode astTree = treemaker(code); + """; + AstNode astTree = treemaker(code); - String correct_error = """ - Error 1 -The return type STRING Does not match the return statement of the function int - """; - typeChecker.visitor(astTree); - String terminal_Errors = normalizeOutput(); - assertEquals(correct_error.trim(), terminal_Errors); - // assertTrue( terminal_Errors.contains(correct_error)); + String correct_error = """ + Error 1 + The return type STRING Does not match the return statement of the function int + """; + typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + assertEquals(correct_error.trim(), terminal_Errors); + // assertTrue( terminal_Errors.contains(correct_error)); } @Test void testTypeCheker17() { /* - * + * Smid fejl vis :Valider at argumenterne i functions call stemmer overens med de forventede + * typer i funktionsdeklaration. */ + String code = """ + var variable:int =4 + fn plus (y:int)-> int{ + + return y+2 + } + var false_result:int =plus("string") + + var true_result:int=plus(5) + + + """; + AstNode astTree = treemaker(code); + + String correct_error = """ + Error 1 + Function Expected type: , as Argument but got) + """; + typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + assertEquals(correct_error.trim(), terminal_Errors); + // assertTrue( terminal_Errors.contains(correct_error)); } } diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md new file mode 100644 index 0000000..669605c --- /dev/null +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md @@ -0,0 +1,42 @@ +# TODO-liste til test af typechecker + +## Håndtering af variabler +- [ ] Kast en fejl, hvis en variabel ikke er erklæret. +- [x] Kast en fejl, hvis en forkert type er tildelt til en variabel. +- [x] Sørg for at variabel-redeklaration i samme scope kaster en fejl. +- [x] Tjek for brug af uerklærede variabler. + +## Funktionshåndtering +- [x] Sikre at funktioner smider fejl vis forkert returtyper. +- [x] Sikre at funktioner ikke smider fejl vis korrect returtyper. +- [ ] Kontroller at alle nødvendige parametre er angivet i et funktionskald. +- [ ] Smid fejl vis fejler:Valider at argumenterne i functions call stemmer overens med de forventede typer i funktionsdeklaration. +- [ ] Smid ikke fejl hvis dette sker:Smid fejl vis fejler:Valider at argumenterne i functions call stemmer overens med de forventede typer i funktionsdeklaration. +- [x] Kast en fejl for retur-udtryk uden for funktioner. +- [ ] Bekræft at funktioner ikke tillader dobbelt deklarationer. + +## Håndtering af arrays +- [ ] Verificer fejlhåndtering ved adgang til indekser uden for grænser. +- [ ] Sørg for typekompatibilitet i array-tildelinger. +- [ ] Kontroller for fejl i array-deklaration med forkerte størrelsestyper. +- [ ] Valider typekonsistens under tildeling af arrayelementer. + +## Håndtering af strukturer +- [ ] Valider fejlhåndtering ved adgang til uerklærede strukturfelter. +- [ ] Kontroller for typefejlmatch i tildelinger af strukturfelter. +- [ ] Sørg for at strukturer ikke tillader dobbelte feltnavne. +- [ ] Bekræft at strukturdeklarationer håndterer scope korrekt. + +## Generel typekontrol +- [ ] Sørg for typekompatibilitet i binære operationer. +- [ ] Valider boolean-udtryk i kontrolstrukturer (if, while). +- [ ] Tjek for typefejl i relationelle og logiske operationer. + +## Fejlhåndtering og beskeder +- [ ] Gennemgå at alle fejlbeskeder er klare og informative. +- [ ] Sørg for at fejltælleren inkrementerer korrekt. + +## Diverse +- [ ] Test håndtering af re-deklaration af indbyggede funktioner. +- [ ] Verificer typekontrol for adgang til egenskaber og metodekald. + From d9d959e5abf5ab4b0db5f6d50660844d08363fbb Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Thu, 9 May 2024 15:45:03 +0200 Subject: [PATCH 53/94] yes --- .../carl/Semantic_A/TypeChecker.java | 4 ++- .../carl/Semantic_A/TypeCheckerTest.java | 27 ++++++++++--------- .../carl/Semantic_A/typechecker_test.md | 2 +- test.carl | 16 +++++------ 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index c2069ba..84049c4 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -545,8 +545,9 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { * Vi skal sige hvis arguemtnet er en forkert type. */ public void visitFunctionCall(FunctionCallNode node) { - System.out.println("we get in here"); + System.out.println("we get in here how?"+node); if (!listOfInbuiltFunctions.contains(node.getFunctionName().toString())) { + HashMap localETable = new HashMap<>(); scopes.add(localETable); if (typeOfReturnFunction.containsKey(node.getFunctionName().toString())) { @@ -570,6 +571,7 @@ public void visitFunctionCall(FunctionCallNode node) { "The function :" + node.getFunctionName().toString() + " May not exist or be out of scope."); } } + } /* diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index c7f4cc1..6ddcf9e 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -444,29 +444,30 @@ fn plus (y:int)-> int{ @Test void testTypeCheker17() { /* - * Smid fejl vis :Valider at argumenterne i functions call stemmer overens med de forventede + * Smid fejl vis :Valider at argumenterne i functions call stemmer overens med + * de forventede * typer i funktionsdeklaration. */ String code = """ - var variable:int =4 - fn plus (y:int)-> int{ - - return y+2 - } - var false_result:int =plus("string") - - var true_result:int=plus(5) + fn plus (y:int)-> int{ + return y+2 + } + // var false_result:int =plus("string") - """; + var true_result:int=plus(5) + + """; AstNode astTree = treemaker(code); String correct_error = """ - Error 1 - Function Expected type: , as Argument but got) - """; + Error 1 + Function Expected type: , as Argument but got + """; typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + System.out.println(terminal_Errors + "We get here"); assertEquals(correct_error.trim(), terminal_Errors); // assertTrue( terminal_Errors.contains(correct_error)); } diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md index 669605c..4ef9d8b 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md @@ -1,7 +1,7 @@ # TODO-liste til test af typechecker ## Håndtering af variabler -- [ ] Kast en fejl, hvis en variabel ikke er erklæret. +- [x] Kast en fejl, hvis en variabel ikke er erklæret. - [x] Kast en fejl, hvis en forkert type er tildelt til en variabel. - [x] Sørg for at variabel-redeklaration i samme scope kaster en fejl. - [x] Tjek for brug af uerklærede variabler. diff --git a/test.carl b/test.carl index 2c2fe94..9486154 100644 --- a/test.carl +++ b/test.carl @@ -1,13 +1,11 @@ -var number:int = 20 -var difficulty:int = 20 -var Goblin : enemy ={ - var difficulty : int = 1 - var health : int = 500 - var symbol : string= "O" - // var difficulty:int = 20 +fn plus (y:int)-> int{ + +return y+2 } +var false_result:int =plus("string") + + var true_result:int=plus(5) -//var number2:int = Goblin.size() -//Goblin.health =20 \ No newline at end of file + \ No newline at end of file From f4e28dfbfcad718246d4bcd1f06aa5988f6db529 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Thu, 9 May 2024 16:23:32 +0200 Subject: [PATCH 54/94] inbuild fejl smidt --- .../carl/Semantic_A/TypeChecker.java | 17 ++- .../carl/Semantic_A/TypeCheckerTest.java | 111 ++++++++++++++---- .../carl/Semantic_A/typechecker_test.md | 26 ++-- 3 files changed, 109 insertions(+), 45 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 84049c4..13c8096 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -149,14 +149,16 @@ public void visistArrayAccesNodeFn(ArrayAccessNode node) { public void visistArrayAssignment(ArrayAssignmentNode node) { String identifier = node.getIdentifier().toString(); Boolean found = false; - found = scopes.getFirst().containsKey(identifier); - + + found = scopes.getLast().containsKey(identifier); + + // System.out.println(activeScope); for (int i = activeScope.getLast(); i < scopes.size(); i++) { if (scopes.get(i).containsKey(identifier)) { found = true; } } - if (!found) { + if (found) { Type arrayType = scopes.getLast().get(identifier); Boolean validTypesaccesTypes = true; @@ -188,7 +190,7 @@ public void visistArrayAssignment(ArrayAssignmentNode node) { } } else { - errorHandler("Identifier:" + identifier + " is alredy used, rename it"); + errorHandler("Array:" + identifier + " Does not exist "); } } @@ -207,7 +209,7 @@ public void visistarrayDekleration(ArrayDefinitionNode node) { found = true; } } - if (!found) { + Type arrayType = getType(node.getType()); Boolean validTypes = true; @@ -226,14 +228,17 @@ public void visistarrayDekleration(ArrayDefinitionNode node) { } if (validTypes) { scopes.getLast().put(identifier, arrayType); + } else { errorHandler("Tried to declare the array:" + identifier + " but argument: " + arguementNumber + " is of type:" + sizeType + " and should be:" + arrayType); } - } else { + if(found){ errorHandler("Identifier:" + identifier + " is alredy used, rename it"); } + + } diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index 6ddcf9e..c7ed0a4 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -224,20 +224,53 @@ void testVisitor() { @Test void testTypeCheker1() { - /* - * Tried to assign the array:" + identifier + " but acces value: " + - * arguementNumber - * + " is of type:" + sizeType + " and should be INT - */ + + String code = """ + + var array: int[3][3] + var array: int[v][3] + """; + AstNode astTree = treemaker(code); + + String correct_error = """ + Error 1 + could not find the variable v + Error 2 + Tried to declare the array:array but argument: 0 is of type:UNKNOWN and should be:INT + Error 3 + Identifier:array is alredy used, rename it + """; + typeChecker.visitor(astTree); + + String terminal_Errors = normalizeOutput(); + System.out.println(terminal_Errors + "We get here"); + assertEquals(correct_error.trim(), terminal_Errors); + // assertTrue( terminal_Errors.contains(correct_error)); } @Test void testTypeCheker2() { - /* - * Tried to assign the array:" + identifier + " but acces value: " + - * arguementNumber - * + " is of type:" + sizeType + " and should be:" + arrayType - */ + String code = """ + + var array: int[3][3] + array[1][1]=10 + array[2][1]="string" + array["string"][2] = 2 + """; + AstNode astTree = treemaker(code); + + String correct_error = """ + Error 1 + Tried to assign the type:STRING to the array:array that has the type:INT, and that is ilegal + Error 2 + Tried to assign the array:array but acces value: 0 is of type:STRING and should be:INT + """; + typeChecker.visitor(astTree); + + String terminal_Errors = normalizeOutput(); + System.out.println(terminal_Errors + "We get here"); + assertEquals(correct_error.trim(), terminal_Errors); + // assertTrue( terminal_Errors.contains(correct_error)); } @Test @@ -289,19 +322,44 @@ void testTypeCheker8() { @Test void testTypeCheker9() { - /* - * "Wrong types for relation operation:" + leftType + ":" + left + " And:" + - * right + ":" + rightType - */ + String code = """ + + fn print (y:int)-> int{ + return 5 + } + + """; + AstNode astTree = treemaker(code); + + String correct_error = """ + Error 1 + You may not redeclare a inbuilt function. The function you tried to redeclare is:print + """;; + typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + assertEquals(correct_error.trim(), terminal_Errors); + // assertTrue( terminal_Errors.contains(correct_error)); } @Test void testTypeCheker10() { - /* - * "Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier - * + " that has the type:" + variableType - * + " And that is hella iligal" - */ + String code = """ + + fn print (y:int)-> int{ + return 5 + } + + """; + AstNode astTree = treemaker(code); + + String correct_error = """ + Error 1 + You may not redeclare a inbuilt function. The function you tried to redeclare is:print + """;; + typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + assertEquals(correct_error.trim(), terminal_Errors); + // assertTrue( terminal_Errors.contains(correct_error)); } public String normalizeOutput() { @@ -445,19 +503,19 @@ fn plus (y:int)-> int{ void testTypeCheker17() { /* * Smid fejl vis :Valider at argumenterne i functions call stemmer overens med - * de forventede + * de forventede //! VIKRER IKKE ÅBENBART * typer i funktionsdeklaration. */ String code = """ - fn plus (y:int)-> int{ - return y+2 - } - // var false_result:int =plus("string") + fn plus (y:int)-> int{ + return y+2 + } + // var false_result:int =plus("string") - var true_result:int=plus(5) + var true_result:int=plus(5) - """; + """; AstNode astTree = treemaker(code); String correct_error = """ @@ -471,4 +529,5 @@ fn plus (y:int)-> int{ assertEquals(correct_error.trim(), terminal_Errors); // assertTrue( terminal_Errors.contains(correct_error)); } + } diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md index 4ef9d8b..c3c8ea9 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md @@ -16,10 +16,13 @@ - [ ] Bekræft at funktioner ikke tillader dobbelt deklarationer. ## Håndtering af arrays -- [ ] Verificer fejlhåndtering ved adgang til indekser uden for grænser. -- [ ] Sørg for typekompatibilitet i array-tildelinger. -- [ ] Kontroller for fejl i array-deklaration med forkerte størrelsestyper. -- [ ] Valider typekonsistens under tildeling af arrayelementer. + +- [x] test for fejl bliver smidt hvis at agumenterne i array [][] ikke er af typen int ved decleration +- [x] test for fejl bliver smidt hvis at agumenterne i array [2][4] ikke er lovlige. i array[][]=2 +- [x] test at array:int smider fejl hvis array[2][2] =string +- [x] Test at ingen fejl bliver smidt hvis array er deklereret kooretk. +- [x] Test for at ingen fejl bliver smidt vis array assignment er korrect + ## Håndtering af strukturer - [ ] Valider fejlhåndtering ved adgang til uerklærede strukturfelter. @@ -28,15 +31,12 @@ - [ ] Bekræft at strukturdeklarationer håndterer scope korrekt. ## Generel typekontrol -- [ ] Sørg for typekompatibilitet i binære operationer. -- [ ] Valider boolean-udtryk i kontrolstrukturer (if, while). -- [ ] Tjek for typefejl i relationelle og logiske operationer. +- [x] Sørg for typekompatibilitet i binære operationer. +- [x] Valider boolean-udtryk i kontrolstrukturer (if, while). +- [x] Tjek for typefejl i relationelle og logiske operationer. RelationOperatorTypeCheck + -## Fejlhåndtering og beskeder -- [ ] Gennemgå at alle fejlbeskeder er klare og informative. -- [ ] Sørg for at fejltælleren inkrementerer korrekt. +## Inbuild functioner +- [x] Test håndtering at fejl bliver smidt for at re-deklaration af indbyggede funktioner. -## Diverse -- [ ] Test håndtering af re-deklaration af indbyggede funktioner. -- [ ] Verificer typekontrol for adgang til egenskaber og metodekald. From c3ccff317991f43959644f969a848877f83f8365 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Thu, 9 May 2024 16:35:37 +0200 Subject: [PATCH 55/94] test til structs smider fejl --- .../carl/Semantic_A/TypeChecker.java | 66 ++++++++++--------- .../carl/Semantic_A/TypeCheckerTest.java | 41 ++++++++---- .../carl/Semantic_A/typechecker_test.md | 7 +- 3 files changed, 68 insertions(+), 46 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index 13c8096..f7a9df4 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -24,6 +24,7 @@ public class TypeChecker { String currentActiveFunction = ""; public Boolean thereWasAnError = false; String currentIdentifierCheck = ""; + Boolean struct_variable_declarion_failed = false; public TypeChecker() { @@ -149,10 +150,10 @@ public void visistArrayAccesNodeFn(ArrayAccessNode node) { public void visistArrayAssignment(ArrayAssignmentNode node) { String identifier = node.getIdentifier().toString(); Boolean found = false; - + found = scopes.getLast().containsKey(identifier); - - // System.out.println(activeScope); + + // System.out.println(activeScope); for (int i = activeScope.getLast(); i < scopes.size(); i++) { if (scopes.get(i).containsKey(identifier)) { found = true; @@ -209,36 +210,34 @@ public void visistarrayDekleration(ArrayDefinitionNode node) { found = true; } } - - Type arrayType = getType(node.getType()); - Boolean validTypes = true; - Type sizeType = Type.UNKNOWN; - int arguementNumber = 0; - List sizes = node.getSizes(); - for (int i = 0; i < sizes.size(); i++) { - AstNode astNode = sizes.get(i); - sizeType = getType(astNode); - if (sizeType != arrayType) { - arguementNumber = i; - validTypes = false; + Type arrayType = getType(node.getType()); - break; - } - } - if (validTypes) { - scopes.getLast().put(identifier, arrayType); + Boolean validTypes = true; + Type sizeType = Type.UNKNOWN; + int arguementNumber = 0; + List sizes = node.getSizes(); + for (int i = 0; i < sizes.size(); i++) { + AstNode astNode = sizes.get(i); + sizeType = getType(astNode); + if (sizeType != arrayType) { + arguementNumber = i; + validTypes = false; - } else { - errorHandler("Tried to declare the array:" + identifier + " but argument: " + arguementNumber - + " is of type:" + sizeType + " and should be:" + arrayType); + break; } + } + if (validTypes) { + scopes.getLast().put(identifier, arrayType); + + } else { + errorHandler("Tried to declare the array:" + identifier + " but argument: " + arguementNumber + + " is of type:" + sizeType + " and should be:" + arrayType); + } - if(found){ + if (found) { errorHandler("Identifier:" + identifier + " is alredy used, rename it"); } - - } @@ -550,7 +549,7 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { * Vi skal sige hvis arguemtnet er en forkert type. */ public void visitFunctionCall(FunctionCallNode node) { - System.out.println("we get in here how?"+node); + System.out.println("we get in here how?" + node); if (!listOfInbuiltFunctions.contains(node.getFunctionName().toString())) { HashMap localETable = new HashMap<>(); @@ -576,7 +575,7 @@ public void visitFunctionCall(FunctionCallNode node) { "The function :" + node.getFunctionName().toString() + " May not exist or be out of scope."); } } - + } /* @@ -597,11 +596,16 @@ public void visitStruct(StructureDefinitionNode node) { scopes.add(localETable); List declarations = node.getVariableDeclarations(); + struct_variable_declarion_failed = false; for (VariableDeclarationNode declaration : declarations) { visitVariableDeclarationforStructs(declaration); } - structTypes.put(identifier, structType); - structVariablesTable.put(identifier, localETable); + if (!struct_variable_declarion_failed) { + structTypes.put(identifier, structType); + structVariablesTable.put(identifier, localETable); + } + + struct_variable_declarion_failed = false; scopes.remove(localETable); } else { @@ -627,6 +631,7 @@ private void visitVariableDeclarationforStructs(VariableDeclarationNode node) { scopes.getLast().put(node.getIdentifier().toString(), typeWeSaveInETable); } else { + struct_variable_declarion_failed = true; errorHandler("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + " that has the type:" + variableType + " And that is hella iligal"); @@ -636,6 +641,7 @@ private void visitVariableDeclarationforStructs(VariableDeclarationNode node) { throw new RuntimeException("variable " + node.getIdentifier() + " already exists in struct"); } } catch (Exception e) { + struct_variable_declarion_failed = true; errorHandler(e.getMessage()); } diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index c7ed0a4..5a6c95f 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -323,18 +323,34 @@ void testTypeCheker8() { @Test void testTypeCheker9() { String code = """ - - fn print (y:int)-> int{ - return 5 - } + var Goblin : enemy ={ + var difficulty : int = 1 + var health : int = 500 + var symbol : string= "O" + var difficulty:int = 20 + } + var Goblin2 : enemy ={ + var difficulty : int = 1 + var health : int = 500 + var symbol : string= "O" + } + var Goblin2 : enemy ={ + var difficulty : int = 1 + var health : int = 500 + var symbol : string= "O" + } - """; + + """; AstNode astTree = treemaker(code); String correct_error = """ - Error 1 - You may not redeclare a inbuilt function. The function you tried to redeclare is:print - """;; + Error 1 + variable difficulty already exists in struct + Error 2 + Struct Goblin2 already exists + """; + ; typeChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); assertEquals(correct_error.trim(), terminal_Errors); @@ -344,7 +360,7 @@ fn print (y:int)-> int{ @Test void testTypeCheker10() { String code = """ - + fn print (y:int)-> int{ return 5 } @@ -353,9 +369,10 @@ fn print (y:int)-> int{ AstNode astTree = treemaker(code); String correct_error = """ - Error 1 - You may not redeclare a inbuilt function. The function you tried to redeclare is:print - """;; + Error 1 + You may not redeclare a inbuilt function. The function you tried to redeclare is:print + """; + ; typeChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); assertEquals(correct_error.trim(), terminal_Errors); diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md index c3c8ea9..66a156c 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/typechecker_test.md @@ -25,10 +25,9 @@ ## Håndtering af strukturer -- [ ] Valider fejlhåndtering ved adgang til uerklærede strukturfelter. -- [ ] Kontroller for typefejlmatch i tildelinger af strukturfelter. -- [ ] Sørg for at strukturer ikke tillader dobbelte feltnavne. -- [ ] Bekræft at strukturdeklarationer håndterer scope korrekt. +- [x] test at fejl bliver smidt når structs redeklereres. +- [x] test for at fejl bliver smidt når strukturer ikke tillader dobbelte feltnavne. + ## Generel typekontrol - [x] Sørg for typekompatibilitet i binære operationer. From 94e2a91a286184c92ec84104d1062d2212d1f21d Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Thu, 9 May 2024 16:40:06 +0200 Subject: [PATCH 56/94] =?UTF-8?q?slettet=20un=C3=B8dig=20prut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carl/Semantic_A/TypeCheckerTest.java | 101 +----------------- 1 file changed, 2 insertions(+), 99 deletions(-) diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index 5a6c95f..bff0675 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -105,15 +105,7 @@ void testErrorHandler() { assertEquals(expectedOutput.trim(), normalizedActualOutput); } - @Test - void testGetType() { - - } - - @Test - void testGetVariable() { - - } + @Test void testRelationOperatorTypeCheck() { @@ -135,25 +127,7 @@ void testRelationOperatorTypeCheck() { assertEquals(Type.BOOLEAN, testfn3, "Should have Type bool"); } - @Test - void testVisitAssignNode() { - - } - - @Test - void testVisitBlockNode() { - - } - - @Test - void testVisitFunctionCall() { - - } - - @Test - void testVisitFunctionDefinition() { - - } + @Test void testVisitIfStatement() { @@ -197,31 +171,6 @@ void testVisitWhileLoop() { "While loop expresion must resolve to bool expresion, and this resolve to Type:" + errorType); } - @Test - void testVisitProgramNode() { - - } - - @Test - void testVisitReturnNode() { - - } - - @Test - void testVisitStatements() { - - } - - @Test - void testVisitStruct() { - - } - - @Test - void testVisitor() { - - } - @Test void testTypeCheker1() { @@ -273,52 +222,6 @@ void testTypeCheker2() { // assertTrue( terminal_Errors.contains(correct_error)); } - @Test - void testTypeCheker3() { - /* - * Tried to assign the type:" + assignType + " to the array:" + identifier - * + " that has the type:" + arrayType + ", and that is ilegal - */ - } - - @Test - void testTypeCheker4() { - /* - * Identifier:" + identifier + " is alredy used, rename it - */ - } - - @Test - void testTypeCheker5() { - /* - * Tried to declare the array:" + identifier + " but argument: " + - * arguementNumber - * + " is of type:" + sizeType + " and should be:" + arrayType - */ - } - - @Test - void testTypeCheker6() { - /* - * Identifier:" + identifier + " is alredy used, rename it - */ - } - - @Test - void testTypeCheker7() { - /* - * Type " + oldType + " does not match " + newType - * - */ - } - - @Test - void testTypeCheker8() { - /* - * "Wrong types for binary operation:" + leftType + ":" + left + " And:" + right - * + ":" + rightType - */ - } @Test void testTypeCheker9() { From d7e1f3e0d67858c4135b95305db48c63ede14499 Mon Sep 17 00:00:00 2001 From: mantarias <32459446+mantarias@users.noreply.github.com> Date: Fri, 10 May 2024 12:11:37 +0200 Subject: [PATCH 57/94] scope --- .../antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 | 2 +- .../carl/Interpreter/InbuildClasses.java | 25 +++- .../carl/Interpreter/Interpreter.java | 109 +++++++++++++----- test.carl | 36 +++--- 4 files changed, 120 insertions(+), 52 deletions(-) diff --git a/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 b/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 index 162bbaf..8b9ea18 100644 --- a/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 +++ b/src/main/antlr4/dk/aau/cs_24_sw_4_16/carl/CARL.g4 @@ -115,7 +115,7 @@ primary ifStatement : 'if' expression block ( 'else if' expression block )* ( 'else' block )? ; whileLoop : 'while' expression block ; returnStatement : 'return' expression? ; -block : '{' (statement | expression)* '}' ; +block : '{' (statement)* '}' ; arrayAccess : IDENTIFIER '[' expression ']' ('[' expression ']')*; propertyAccess : structType '.' IDENTIFIER ('.' IDENTIFIER)? ; coordinateDeclaration : 'var' IDENTIFIER ':' 'coord' '=' '(' expression ',' expression ')' ;//Virker ikke nødvendigt, hvorfor ikke bare bruge arrayAcces? diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java index f95ecc2..f2c5cac 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java @@ -15,14 +15,29 @@ public static void print(FunctionCallNode node, Stack> if (argument instanceof StatementNode) { toPrint.append(((StatementNode) argument).getNode()).append(" "); } else if (argument instanceof IdentifierNode) { - if (scopes.getFirst().containsKey(argument.toString())) { - toPrint.append(scopes.getFirst().get(argument.toString()).toString()).append(" "); - } else { - for (int i = activeScope.getLast(); i < scopes.size(); i++) { + int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; + boolean found = false; + for (int i = scopes.size() - 1; i >= towards; i--) { + if (scopes.get(i).containsKey(argument.toString())) { + toPrint.append(scopes.get(i).get(argument.toString()).toString()).append(" "); + found = true; + break; + } + } + + if (!found) { + int from = 0; + if (!activeScope.isEmpty()) { + from = activeScope.getFirst(); + } else { + from = scopes.size() - 1; + } + for (int i = from; i >= 0; i--) { if (scopes.get(i).containsKey(argument.toString())) { - toPrint.append(scopes.get(i).get(argument.toString()).toString()).append(" "); + toPrint.append(scopes.getFirst().get(argument.toString()).toString()).append(" "); } } + } } else if (argument instanceof FloatNode) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java index 75c26bd..7167e62 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java @@ -30,7 +30,7 @@ public Interpreter() { tileInformationWall = new HashMap<>(); scopes = new Stack<>(); activeScope = new ArrayDeque<>(); - activeScope.push(0); +// activeScope.push(0); scopes.add(vTable); rooms = new ArrayList<>(); } @@ -45,8 +45,8 @@ public AstNode visit(AstNode node) { } return node; } - public AstNode roomCall(MethodCallNode node) - { + + public AstNode roomCall(MethodCallNode node) { if (node.getPropertyAccessContext().getIdentifiers().get(0).toString().equals("size")) { return new IntNode(rooms.size()); } else if (node.getPropertyAccessContext().getIdentifiers().get(0).toString().equals("get")) { @@ -63,6 +63,7 @@ public AstNode roomCall(MethodCallNode node) } throw new RuntimeException("method call went wrong"); } + public AstNode visit(MethodCallNode node) { HashMap> list; switch (node.getPropertyAccessContext().getList()) { @@ -230,27 +231,61 @@ public void visit(IfStatementNode node) { public AstNode getVariable(IdentifierNode node) { // for (HashMap vTable : scopes) { - if (scopes.getFirst().containsKey(node.getIdentifier())) { - return scopes.getFirst().get(node.getIdentifier()); - } - for (int i = activeScope.getLast(); i < scopes.size(); i++) { + int towards =!activeScope.isEmpty() ? activeScope.getLast() : 0; + for (int i = scopes.size() - 1; i >= towards; i--) { + if (scopes.get(i).containsKey(node.getIdentifier())) { + return scopes.get(i).get(node.getIdentifier()); + } + } + int from = 0; + if (!activeScope.isEmpty()) { + from = activeScope.getFirst(); + } else { + from = scopes.size() - 1; + } + for (int i = from; i >= 0; i--) { if (scopes.get(i).containsKey(node.getIdentifier())) { return scopes.get(i).get(node.getIdentifier()); } } +// if (scopes.getFirst().containsKey(node.getIdentifier())) { +// return scopes.getFirst().get(node.getIdentifier()); +// } throw new RuntimeException("could not find the variable " + node.getIdentifier()); } public void visit(AssignmentNode node) { - for (HashMap vTable : scopes) { - if (vTable.containsKey(node.getIdentifier().toString())) { - AstNode nodeToChange = vTable.get(node.getIdentifier().toString()); + int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; + for (int i = scopes.size() - 1; i >= towards; i--) { + if (scopes.get(i).containsKey(node.getIdentifier().getIdentifier())) { +// if (vTable.containsKey(node.getIdentifier().toString())) { + AstNode nodeToChange = scopes.get(i).get(node.getIdentifier().toString()); + AstNode toChange = node.getValue(); + replaceValue(nodeToChange, toChange); + return; + } + } + int from = 0; + if (!activeScope.isEmpty()) { + from = activeScope.getFirst(); + } else { + from = scopes.size() - 1; + } + for (int i = from; i >= 0; i--) { + if (scopes.get(i).containsKey(node.getIdentifier())) { + AstNode nodeToChange = scopes.get(i).get(node.getIdentifier().toString()); AstNode toChange = node.getValue(); replaceValue(nodeToChange, toChange); return; } } +// if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { +// AstNode nodeToChange = scopes.getFirst().get(node.getIdentifier().toString()); +// AstNode toChange = node.getValue(); +// replaceValue(nodeToChange, toChange); +// return; +// } throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); } @@ -258,7 +293,8 @@ public void visit(AssignmentNode node) { public void visit(VariableDeclarationNode node) { - if (!idExists(node.getIdentifier().toString())) { + if (!scopes.getLast().containsKey(node.getIdentifier().getIdentifier())) { +// if (!idExists(node.getIdentifier().toString())) { AstNode toChange = node.getValue(); if (toChange instanceof FunctionCallNode) { @@ -289,7 +325,7 @@ public void visit(VariableDeclarationNode node) { } } else { - throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); + throw new RuntimeException("variable " + node.getIdentifier() + " already exists in the current scope"); } } @@ -307,9 +343,9 @@ public AstNode visit(ArrayAccessNode node) { return ((ArrayNode) getVariable(node.getIdentifier())) .get( - node.getIndices().stream().mapToInt( - astNode -> evaluate_int(astNode).getValue() - ).toArray() + node.getIndices().stream().mapToInt( + astNode -> evaluate_int(astNode).getValue() + ).toArray() ); } @@ -338,31 +374,31 @@ public void visit(ArrayAssignmentNode node) { ((ArrayNode) getVariable(node.getIdentifier())).set(value, indices); } - private IntNode evaluate_int(AstNode node){ + private IntNode evaluate_int(AstNode node) { if (node instanceof BinaryOperatorNode) { return (IntNode) visit((BinaryOperatorNode) node); } else if (node instanceof IdentifierNode) { var value = getVariable((IdentifierNode) node); - if (value instanceof IntNode ) + if (value instanceof IntNode) return (IntNode) value; else throw new RuntimeException("Type mismatch: Expected " + ((IdentifierNode) node).getIdentifier() + " to be an int, got " + value.getClass()); - } else if (node instanceof FunctionCallNode){ + } else if (node instanceof FunctionCallNode) { var value = visit((FunctionCallNode) node); - if (value instanceof IntNode ) + if (value instanceof IntNode) return (IntNode) value; else throw new RuntimeException("Type mismatch: Expected " + ((FunctionCallNode) node).getFunctionName().getIdentifier() + "() to return an int, got " + value.getClass()); - } else if (node instanceof RelationsAndLogicalOperatorNode){ + } else if (node instanceof RelationsAndLogicalOperatorNode) { var value = visit((RelationsAndLogicalOperatorNode) node); - if (value instanceof IntNode ) + if (value instanceof IntNode) return (IntNode) value; else throw new RuntimeException("Type mismatch: " + ((RelationsAndLogicalOperatorNode) node).operator + " operator doesn't return an int"); } else if (node instanceof IntNode) { return (IntNode) node; - } else if (node instanceof ExpressionNode){ + } else if (node instanceof ExpressionNode) { return evaluate_int(((ExpressionNode) node).getNode()); } else { throw new RuntimeException("Expected an integer, got " + node.getClass()); @@ -380,15 +416,36 @@ public void visit(ArrayDefinitionNode node) { private boolean idExists(String id) { boolean found = false; - if (scopes.getFirst().containsKey(id)) { - found = true; + int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; + for (int i = scopes.size() - 1; i >= towards; i--) { + if (scopes.get(i).containsKey(id)) { + found = true; + } } - - for (int i = activeScope.getLast(); i < scopes.size(); i++) { + int from = 0; + if (!activeScope.isEmpty()) { + from = activeScope.getFirst(); + } else { + from = scopes.size() - 1; + } + for (int i = from; i >= 0; i--) { if (scopes.get(i).containsKey(id)) { found = true; } } +// if (scopes.getFirst().containsKey(id)) { +// found = true; +// } + +// if (scopes.getFirst().containsKey(id)) { +// found = true; +// } +// +// for (int i = activeScope.getLast(); i < scopes.size(); i++) { +// if (scopes.get(i).containsKey(id)) { +// found = true; +// } +// } return found; } diff --git a/test.carl b/test.carl index 9df0916..1b1366d 100644 --- a/test.carl +++ b/test.carl @@ -1,22 +1,18 @@ -var Orc : enemy = { - var difficulty : int = 1 - var health : int = 200 - var symbol : string= "O" +var x:int =2 + +fn plus (y:int)-> int{ + var help : int = x + y + return help } -var Goblin : enemy ={ - var difficulty : int = 1 - var health : int = 500 - var symbol : string= "O" -} -var Goblin2 : enemy ={ - var difficulty : int = 1 - var health : int = 500 - var symbol : string= "O" -} -var Goblin3 : enemy ={ - var difficulty : int = 1 - var health : int = 500 - var symbol : string= "O" -} -var test : int = 1..enemy.size() + +var test : string = "test" print(test) + +if true { + var x:int = 5 // + var test : int = 5 + test = 6 + var result : int = plus(2) + print(result) +} +print(test) \ No newline at end of file From a4987e03b304c0d284889cc1681dbf51643ab5d2 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sun, 12 May 2024 17:19:52 +0200 Subject: [PATCH 58/94] Dymnamic scope Og Ny navngivning --- .../carl/CstToAst/ArrayDefinitionNode.java | 1 - .../carl/CstToAst/BinaryOperatorNode.java | 6 +-- .../cs_24_sw_4_16/carl/CstToAst/CstToAst.java | 4 +- .../carl/CstToAst/IdentifierNode.java | 4 -- ...nterpreter.java => EvaluatorExecutor.java} | 4 +- .../carl/Interpreter/InbuildClasses.java | 16 +++--- .../java/dk/aau/cs_24_sw_4_16/carl/Main.java | 4 +- .../carl/Semantic_A/TypeChecker.java | 26 ++++++---- .../carl/Semantic_A/TypeCheckerTest.java | 2 +- .../carl/SimpleFunctionIntegrationTest.java | 52 +++++++++---------- test.carl | 1 + 11 files changed, 61 insertions(+), 59 deletions(-) rename src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/{Interpreter.java => EvaluatorExecutor.java} (99%) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayDefinitionNode.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayDefinitionNode.java index d2f167a..5e83aa5 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayDefinitionNode.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/ArrayDefinitionNode.java @@ -7,7 +7,6 @@ public class ArrayDefinitionNode extends AstNode { @Getter private final TypeNode type; - // we need this only if dynamic sizing is allowed @Getter private final List sizes; @Getter private final IdentifierNode identifier; diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BinaryOperatorNode.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BinaryOperatorNode.java index d972b3a..41101cc 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BinaryOperatorNode.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BinaryOperatorNode.java @@ -1,6 +1,6 @@ package dk.aau.cs_24_sw_4_16.carl.CstToAst; -import dk.aau.cs_24_sw_4_16.carl.Interpreter.Interpreter; +import dk.aau.cs_24_sw_4_16.carl.Interpreter.EvaluatorExecutor; public class BinaryOperatorNode extends AstNode { private final AstNode left; @@ -35,7 +35,7 @@ public static AstNode performOperation(int leftValue, int rightValue, String ope case "*" -> new IntNode(String.valueOf(leftValue * rightValue)); case "/" -> new IntNode(String.valueOf(leftValue / rightValue)); case "%" -> new IntNode(String.valueOf(leftValue % rightValue)); - case ".." -> new IntNode(String.valueOf(Interpreter.rand.nextInt(leftValue, rightValue))); + case ".." -> new IntNode(String.valueOf(EvaluatorExecutor.rand.nextInt(leftValue, rightValue))); default -> throw new IllegalArgumentException("Invalid operator: " + operator); }; } @@ -47,7 +47,7 @@ public static AstNode performOperation(float leftValue, float rightValue, String case "*" -> new FloatNode(String.valueOf(leftValue * rightValue)); case "/" -> new FloatNode(String.valueOf(leftValue / rightValue)); case "%" -> new FloatNode(String.valueOf(leftValue % rightValue)); - case ".." -> new IntNode(String.valueOf(Interpreter.rand.nextFloat(leftValue, rightValue))); + case ".." -> new IntNode(String.valueOf(EvaluatorExecutor.rand.nextFloat(leftValue, rightValue))); default -> throw new IllegalArgumentException("Invalid operator: " + operator); }; } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAst.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAst.java index 738335b..287cf25 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAst.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAst.java @@ -3,7 +3,7 @@ import dk.aau.cs_24_sw_4_16.carl.CARLLexer; import dk.aau.cs_24_sw_4_16.carl.CARLParser; -import dk.aau.cs_24_sw_4_16.carl.Interpreter.Interpreter; +import dk.aau.cs_24_sw_4_16.carl.Interpreter.EvaluatorExecutor; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; @@ -24,7 +24,7 @@ public static void main(String[] args) throws IOException { ParseTree tree = parser.program(); CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter inter = new Interpreter(); + EvaluatorExecutor inter = new EvaluatorExecutor(); inter.visit(astRoot); } catch (Exception e){ diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/IdentifierNode.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/IdentifierNode.java index 0fe1a08..7271bf2 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/IdentifierNode.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/IdentifierNode.java @@ -4,14 +4,10 @@ @Getter public class IdentifierNode extends AstNode { - - String identifier; - public IdentifierNode(String identifier) { this.identifier = identifier; } - @Override public String toString() { return identifier; diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java similarity index 99% rename from src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java rename to src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java index 2cf5926..6f6456a 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java @@ -6,7 +6,7 @@ import java.util.*; import java.util.stream.IntStream; -public class Interpreter { +public class EvaluatorExecutor { HashMap fTable; HashMap vTable; Stack> scopes; @@ -22,7 +22,7 @@ public class Interpreter { //the worst case we just get worse randomness. public static Random rand = new Random(); - public Interpreter() { + public EvaluatorExecutor() { fTable = new HashMap<>(); vTable = new HashMap<>(); tileInformationEnemy = new HashMap<>(); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java index f2c5cac..b153353 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java @@ -88,10 +88,10 @@ public static void generateRooms(FunctionCallNode node, Stack rooms.size()) { - int roomWidth = Interpreter.rand.nextInt(minRoomSize, maxRoomSize); - int roomHeight = Interpreter.rand.nextInt(minRoomSize, maxRoomSize); - int x = Interpreter.rand.nextInt(1, map.getSizes().get(1) - roomWidth); - int y = Interpreter.rand.nextInt(1, map.getSizes().get(0) - roomHeight); + int roomWidth = EvaluatorExecutor.rand.nextInt(minRoomSize, maxRoomSize); + int roomHeight = EvaluatorExecutor.rand.nextInt(minRoomSize, maxRoomSize); + int x = EvaluatorExecutor.rand.nextInt(1, map.getSizes().get(1) - roomWidth); + int y = EvaluatorExecutor.rand.nextInt(1, map.getSizes().get(0) - roomHeight); HashMap room = new HashMap<>(); if (!overlap(x, y, roomWidth, roomHeight, map)) { for (int i = y; i < y + roomHeight; i++) { @@ -156,8 +156,8 @@ public static void generateCorridors(FunctionCallNode node, Stack> scopes, HashMap> tileInformationEnemy, List> rooms) { ArrayNode map = ((ArrayNode) scopes.getFirst().get("map")); - int yPlayer = Interpreter.rand.nextInt(((IntNode) rooms.get(rooms.size() - 1).get("x")).getValue(), (((IntNode) rooms.get(rooms.size() - 1).get("x")).getValue() + ((IntNode) rooms.get(rooms.size() - 1).get("width")).getValue())); - int xPlayer = Interpreter.rand.nextInt(((IntNode) rooms.get(rooms.size() - 1).get("y")).getValue(), (((IntNode) rooms.get(rooms.size() - 1).get("y")).getValue() + ((IntNode) rooms.get(rooms.size() - 1).get("height")).getValue())); + int yPlayer = EvaluatorExecutor.rand.nextInt(((IntNode) rooms.get(rooms.size() - 1).get("x")).getValue(), (((IntNode) rooms.get(rooms.size() - 1).get("x")).getValue() + ((IntNode) rooms.get(rooms.size() - 1).get("width")).getValue())); + int xPlayer = EvaluatorExecutor.rand.nextInt(((IntNode) rooms.get(rooms.size() - 1).get("y")).getValue(), (((IntNode) rooms.get(rooms.size() - 1).get("y")).getValue() + ((IntNode) rooms.get(rooms.size() - 1).get("height")).getValue())); map.set(new StringNode("p"), xPlayer, yPlayer); } @@ -290,12 +290,12 @@ private static boolean overlap(int x, int y, int width, int height, ArrayNode ma public static void setSeed(FunctionCallNode node) { if (node.getArguments().size() == 1) { if (node.getArgument(0) instanceof IntNode) { - Interpreter.rand = new Random(((IntNode) node.getArgument(0)).getValue()); + EvaluatorExecutor.rand = new Random(((IntNode) node.getArgument(0)).getValue()); } else { throw new RuntimeException("setSeed only supports int arguments"); } } else if (node.getArguments().isEmpty()) { - Interpreter.rand = new Random(); + EvaluatorExecutor.rand = new Random(); } else { throw new RuntimeException("setSeed called accepts only a singular int argument or none"); } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index 40db5a6..207b105 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -2,7 +2,7 @@ import dk.aau.cs_24_sw_4_16.carl.CstToAst.AstNode; import dk.aau.cs_24_sw_4_16.carl.CstToAst.CstToAstVisitor; -import dk.aau.cs_24_sw_4_16.carl.Interpreter.Interpreter; +import dk.aau.cs_24_sw_4_16.carl.Interpreter.EvaluatorExecutor; import dk.aau.cs_24_sw_4_16.carl.Semantic_A.TypeChecker; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; @@ -48,7 +48,7 @@ public static void main(String... args) { typeChecker.visitor(astRoot); if (!typeChecker.thereWasAnError) { - Interpreter inter = new Interpreter(); + EvaluatorExecutor inter = new EvaluatorExecutor(); inter.visit(astRoot); } // Interpreter is a class that can traverse the AST and interpret or execute the diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index f7a9df4..e6d51c8 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -340,13 +340,13 @@ public Type binaryOperatorTypeCheck(BinaryOperatorNode node) { private void visitVariableDeclaration(VariableDeclarationNode node) { try { - boolean found = scopes.getFirst().containsKey(node.getIdentifier().toString()); + boolean found = scopes.getLast().containsKey(node.getIdentifier().toString()); - for (int i = activeScope.getLast(); i < scopes.size(); i++) { + /* for (int i = activeScope.getLast(); i < scopes.size(); i++) { if (scopes.get(i).containsKey(node.getIdentifier().toString())) { found = true; } - } + } */ if (!found) {// Vi skal tjekke variable type mod det den type vi assigner til variablen. String identifier = node.getIdentifier().toString(); @@ -367,7 +367,7 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { } } else { - throw new RuntimeException("variable " + node.getIdentifier() + " already exists"); + throw new RuntimeException("variable: " + node.getIdentifier() + " already exists in the scope"); } } catch (Exception e) { errorHandler(e.getMessage()); @@ -377,10 +377,13 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { public Type getVariable(IdentifierNode node) { - if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { + if (scopes.getLast().containsKey(node.getIdentifier().toString())) { + // System.out.println("234324234"+scopes.getFirst()); currentIdentifierCheck = node.getIdentifier().toString(); - return scopes.getFirst().get(node.getIdentifier().toString()); + return scopes.getLast().get(node.getIdentifier().toString()); } + // System.out.println("We get in here:"+node.getIdentifier().toString()); + // System.out.println("The scopes:"+scopes); for (int i = activeScope.getLast(); i < scopes.size(); i++) { if (scopes.get(i).containsKey(node.getIdentifier().toString())) { currentIdentifierCheck = node.getIdentifier().toString(); @@ -416,11 +419,14 @@ public void visitAssignNode(AssignmentNode node) { } boolean foundIdentifier = false; - for (HashMap ETable : scopes) { + for (int i = scopes.size() - 1; 0 <= i; i--) { + // System.out.println("This many scopes:" + i + ":" + scopes.get(i)); + HashMap ETable=scopes.get(i); + // System.out.println("Here it break2s"+ETable); if (true) { - System.out.println("Identifier" + node.getIdentifier().toString()); - System.out.println("Etable:" + ETable); + // System.out.println("Identifier" + node.getIdentifier().toString()); + // System.out.println("Etable:" + ETable); } if (ETable.containsKey(node.getIdentifier().toString())) {// hvis x er i scope foundIdentifier = true; @@ -549,7 +555,7 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { * Vi skal sige hvis arguemtnet er en forkert type. */ public void visitFunctionCall(FunctionCallNode node) { - System.out.println("we get in here how?" + node); + // System.out.println("we get in here how?" + node); if (!listOfInbuiltFunctions.contains(node.getFunctionName().toString())) { HashMap localETable = new HashMap<>(); diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index bff0675..2ea98a9 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -321,7 +321,7 @@ void testTypeCheker12() { String correct_error = """ Error 1 - variable test_variable already exists"""; + variable: test_variable already exists in the scope"""; typeChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); assertEquals(correct_error.trim(), terminal_Errors); diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java index c6bc9e4..e3d4fbb 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java @@ -2,7 +2,7 @@ import dk.aau.cs_24_sw_4_16.carl.CstToAst.AstNode; import dk.aau.cs_24_sw_4_16.carl.CstToAst.CstToAstVisitor; -import dk.aau.cs_24_sw_4_16.carl.Interpreter.Interpreter; +import dk.aau.cs_24_sw_4_16.carl.Interpreter.EvaluatorExecutor; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; @@ -46,7 +46,7 @@ public void testingPrintSatement() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); assertEquals("\"test\"".trim(), outContent.toString().trim(), "expected the output to be test"); @@ -68,7 +68,7 @@ public void testingVariable() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); // Assertions can be extended based on the print output or internal state checks @@ -91,7 +91,7 @@ public void testingIncrementOperator() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); assertEquals("2".trim(), outContent.toString().trim(), "Expected the output to be 2 because 'l' was incremented once."); @@ -112,7 +112,7 @@ public void testingAddition() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); // Assertions can be extended based on the print output or internal state checks @@ -140,7 +140,7 @@ public void testingIfStatement() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); // Assertions can be extended based on the print output or internal state checks @@ -170,7 +170,7 @@ public void testingIfElseChain() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); // Assertions can be extended based on the print output or internal state checks @@ -192,7 +192,7 @@ public void testingMult() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); // Assertions can be extended based on the print output or internal state checks @@ -217,7 +217,7 @@ public void testingWhile() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); // Assertions can be extended based on the print output or internal state checks @@ -242,7 +242,7 @@ fn calculate() -> int { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); // Assertions can be extended based on the print output or internal state checks @@ -265,7 +265,7 @@ public void testingSubtraction() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); // Assertions can be extended based on the print output or internal state checks @@ -287,7 +287,7 @@ public void testingDivision() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); // Assertions can be extended based on the print output or internal state checks @@ -309,7 +309,7 @@ public void testingModulus() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); // Assertions can be extended based on the print output or internal state checks @@ -332,7 +332,7 @@ public void testingInt() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); assertEquals("42".trim(), outContent.toString().trim()); @@ -353,7 +353,7 @@ public void testingFloat() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); assertEquals("42.5".trim(), outContent.toString().trim()); @@ -374,7 +374,7 @@ public void testingString() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); assertEquals("\"test\"".trim(), outContent.toString().trim()); @@ -395,7 +395,7 @@ public void testingBool() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); assertEquals("true".trim(), outContent.toString().trim()); @@ -439,7 +439,7 @@ public void testingSeed() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); @@ -462,7 +462,7 @@ public void testingSeed2() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); @@ -489,7 +489,7 @@ public void testingEntireProcedure() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); // do not touch the indentation of the check it will break @@ -567,7 +567,7 @@ public void testingEntireProcedure2() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); @@ -646,7 +646,7 @@ public void testingStruct1() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); assertEquals("5300".trim(), outContent.toString().trim()); @@ -675,7 +675,7 @@ public void testingStruct2() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); assertEquals("\"orcacnian\"".trim(), outContent.toString().trim()); @@ -704,7 +704,7 @@ public void testingStruct3() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); assertEquals("\"orcacnian\"".trim(), outContent.toString().trim()); @@ -733,7 +733,7 @@ public void testingStruct4() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); assertEquals("\"orcacnian\"".trim(), outContent.toString().trim()); @@ -762,7 +762,7 @@ public void testingStruct5() throws Exception { CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - Interpreter interpreter = new Interpreter(); + EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); assertEquals("1".trim(), outContent.toString().trim()); diff --git a/test.carl b/test.carl index 1e3e296..4ebb30c 100644 --- a/test.carl +++ b/test.carl @@ -12,6 +12,7 @@ if true { var x:int = 5 // var test : int = 5 test = 6 + var test :int = 20 var result : int = plus(2) print(result) } From a8915ca07544daa93600c009a276e3af2e4b143f Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sun, 12 May 2024 17:44:50 +0200 Subject: [PATCH 59/94] Orthangnality implemented --- .../carl/CstToAst/BinaryOperatorNode.java | 37 +++++ .../carl/Interpreter/EvaluatorExecutor.java | 126 ++++++++++-------- .../carl/Interpreter/InbuildClasses.java | 2 + .../carl/Semantic_A/TypeChecker.java | 37 ++--- test.carl | 12 +- 5 files changed, 141 insertions(+), 73 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BinaryOperatorNode.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BinaryOperatorNode.java index 41101cc..81b2ce2 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BinaryOperatorNode.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BinaryOperatorNode.java @@ -22,7 +22,18 @@ public static AstNode getAstNodeValue(AstNode left, AstNode right, String operat float leftValue = ((FloatNode) left).getValue(); float rightValue = ((FloatNode) right).getValue(); return performOperation(leftValue, rightValue, operator); + }else if (left instanceof FloatNode && right instanceof IntNode) { + float leftValue = ((FloatNode) left).getValue(); + float rightValue = ((IntNode) right).getValue(); + return performOperation(leftValue, rightValue, operator); + }else if (left instanceof IntNode && right instanceof FloatNode) { + float leftValue = ((IntNode) left).getValue(); + float rightValue = ((FloatNode) right).getValue(); + return performOperation(leftValue, rightValue, operator); } + + + return null; } @@ -52,6 +63,32 @@ public static AstNode performOperation(float leftValue, float rightValue, String }; } + + public static AstNode performOperation(float leftValue, int rightValue, String operator) { + return switch (operator) { + case "+" -> new FloatNode(String.valueOf(leftValue + rightValue)); + case "-" -> new FloatNode(String.valueOf(leftValue - rightValue)); + case "*" -> new FloatNode(String.valueOf(leftValue * rightValue)); + case "/" -> new FloatNode(String.valueOf(leftValue / rightValue)); + case "%" -> new FloatNode(String.valueOf(leftValue % rightValue)); + case ".." -> new IntNode(String.valueOf(EvaluatorExecutor.rand.nextFloat(leftValue, rightValue))); + default -> throw new IllegalArgumentException("Invalid operator: " + operator); + }; + } + + public static AstNode performOperation(int leftValue, float rightValue, String operator) { + return switch (operator) { + case "+" -> new FloatNode(String.valueOf(leftValue + rightValue)); + case "-" -> new FloatNode(String.valueOf(leftValue - rightValue)); + case "*" -> new FloatNode(String.valueOf(leftValue * rightValue)); + case "/" -> new FloatNode(String.valueOf(leftValue / rightValue)); + case "%" -> new FloatNode(String.valueOf(leftValue % rightValue)); + case ".." -> new IntNode(String.valueOf(EvaluatorExecutor.rand.nextFloat(leftValue, rightValue))); + default -> throw new IllegalArgumentException("Invalid operator: " + operator); + }; + } + + public AstNode getLeft() { return left; } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java index 6f6456a..be438ef 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java @@ -15,11 +15,11 @@ public class EvaluatorExecutor { HashMap> tileInformationFloor; HashMap> tileInformationWall; List> rooms; - //This will be the same instance for all instances of Interpreter - //This might have unexpected consequences if we expand the program to use - //more than one instance of Interpreter at a time, but it doesn't yet, so - //it doesn't really matter. There's no better way of doing this, and in - //the worst case we just get worse randomness. + // This will be the same instance for all instances of Interpreter + // This might have unexpected consequences if we expand the program to use + // more than one instance of Interpreter at a time, but it doesn't yet, so + // it doesn't really matter. There's no better way of doing this, and in + // the worst case we just get worse randomness. public static Random rand = new Random(); public EvaluatorExecutor() { @@ -30,7 +30,7 @@ public EvaluatorExecutor() { tileInformationWall = new HashMap<>(); scopes = new Stack<>(); activeScope = new ArrayDeque<>(); -// activeScope.push(0); + // activeScope.push(0); scopes.add(vTable); rooms = new ArrayList<>(); } @@ -53,7 +53,8 @@ public AstNode roomCall(MethodCallNode node) { if (((ArgumentListNode) node.getValue()).getList().get(0) instanceof IntNode) { int index = ((IntNode) ((ArgumentListNode) node.getValue()).getList().get(0)).getValue(); if (index < rooms.size()) { - return rooms.get(((IntNode) ((ArgumentListNode) node.getValue()).getList().get(0)).getValue()).get(node.getIdentifierNode().toString()); + return rooms.get(((IntNode) ((ArgumentListNode) node.getValue()).getList().get(0)).getValue()) + .get(node.getIdentifierNode().toString()); } else { throw new RuntimeException("out of bounds"); } @@ -190,18 +191,19 @@ public void replaceValue(AstNode node, AstNode node2) { if (toChange instanceof MethodCallNode) { toChange = visit((MethodCallNode) toChange); } - if (toChange instanceof ArrayAccessNode) toChange = visit((ArrayAccessNode) toChange); + if (toChange instanceof ArrayAccessNode) + toChange = visit((ArrayAccessNode) toChange); AstNode finalToChange = toChange; switch (node) { case IntNode intNode when finalToChange instanceof IntNode -> - intNode.setValue(((IntNode) finalToChange).getValue()); + intNode.setValue(((IntNode) finalToChange).getValue()); case FloatNode floatNode when finalToChange instanceof FloatNode -> - floatNode.setValue(((FloatNode) finalToChange).getValue()); + floatNode.setValue(((FloatNode) finalToChange).getValue()); case StringNode stringNode when finalToChange instanceof StringNode -> - stringNode.setValue(((StringNode) finalToChange).getValue()); + stringNode.setValue(((StringNode) finalToChange).getValue()); case BoolNode boolNode when finalToChange instanceof BoolNode -> - boolNode.setValue(((BoolNode) finalToChange).getValue()); + boolNode.setValue(((BoolNode) finalToChange).getValue()); case null, default -> throw new RuntimeException("Type mismatch"); } } @@ -230,9 +232,9 @@ public void visit(IfStatementNode node) { } public AstNode getVariable(IdentifierNode node) { -// for (HashMap vTable : scopes) { + // for (HashMap vTable : scopes) { - int towards =!activeScope.isEmpty() ? activeScope.getLast() : 0; + int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; for (int i = scopes.size() - 1; i >= towards; i--) { if (scopes.get(i).containsKey(node.getIdentifier())) { return scopes.get(i).get(node.getIdentifier()); @@ -249,9 +251,9 @@ public AstNode getVariable(IdentifierNode node) { return scopes.get(i).get(node.getIdentifier()); } } -// if (scopes.getFirst().containsKey(node.getIdentifier())) { -// return scopes.getFirst().get(node.getIdentifier()); -// } + // if (scopes.getFirst().containsKey(node.getIdentifier())) { + // return scopes.getFirst().get(node.getIdentifier()); + // } throw new RuntimeException("could not find the variable " + node.getIdentifier()); } @@ -259,7 +261,7 @@ public void visit(AssignmentNode node) { int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; for (int i = scopes.size() - 1; i >= towards; i--) { if (scopes.get(i).containsKey(node.getIdentifier().getIdentifier())) { -// if (vTable.containsKey(node.getIdentifier().toString())) { + // if (vTable.containsKey(node.getIdentifier().toString())) { AstNode nodeToChange = scopes.get(i).get(node.getIdentifier().toString()); AstNode toChange = node.getValue(); replaceValue(nodeToChange, toChange); @@ -280,21 +282,21 @@ public void visit(AssignmentNode node) { return; } } -// if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { -// AstNode nodeToChange = scopes.getFirst().get(node.getIdentifier().toString()); -// AstNode toChange = node.getValue(); -// replaceValue(nodeToChange, toChange); -// return; -// } + // if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { + // AstNode nodeToChange = + // scopes.getFirst().get(node.getIdentifier().toString()); + // AstNode toChange = node.getValue(); + // replaceValue(nodeToChange, toChange); + // return; + // } throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); } - public void visit(VariableDeclarationNode node) { if (!scopes.getLast().containsKey(node.getIdentifier().getIdentifier())) { -// if (!idExists(node.getIdentifier().toString())) { + // if (!idExists(node.getIdentifier().toString())) { AstNode toChange = node.getValue(); if (toChange instanceof FunctionCallNode) { @@ -329,13 +331,12 @@ public void visit(VariableDeclarationNode node) { } } - private int[] astNodeListToIntArray(List ints) { return Arrays.stream(ints.toArray(new AstNode[0])).mapToInt(i -> evaluate_int(i).getValue()).toArray(); } public AstNode visit(ArrayAccessNode node) { - //Explanation: + // Explanation: // 1. Get the ArrayNode behind the identifier. // 2. Convert the List into int[] (through evaluate_int()) // 3. ??? @@ -344,9 +345,7 @@ public AstNode visit(ArrayAccessNode node) { return ((ArrayNode) getVariable(node.getIdentifier())) .get( node.getIndices().stream().mapToInt( - astNode -> evaluate_int(astNode).getValue() - ).toArray() - ); + astNode -> evaluate_int(astNode).getValue()).toArray()); } public void visit(ArrayAssignmentNode node) { @@ -364,12 +363,12 @@ public void visit(ArrayAssignmentNode node) { } else if (node.getValue() instanceof RelationsAndLogicalOperatorNode) { value = visit((RelationsAndLogicalOperatorNode) node.getValue()); } else { - //Those were all the checks made by visit(AssignmentNode) - //Surely there can't be any other checks that need to be made + // Those were all the checks made by visit(AssignmentNode) + // Surely there can't be any other checks that need to be made value = node.getValue(); } - //These are the only checks made in + // These are the only checks made in ((ArrayNode) getVariable(node.getIdentifier())).set(value, indices); } @@ -383,19 +382,23 @@ private IntNode evaluate_int(AstNode node) { if (value instanceof IntNode) return (IntNode) value; else - throw new RuntimeException("Type mismatch: Expected " + ((IdentifierNode) node).getIdentifier() + " to be an int, got " + value.getClass()); + throw new RuntimeException("Type mismatch: Expected " + ((IdentifierNode) node).getIdentifier() + + " to be an int, got " + value.getClass()); } else if (node instanceof FunctionCallNode) { var value = visit((FunctionCallNode) node); if (value instanceof IntNode) return (IntNode) value; else - throw new RuntimeException("Type mismatch: Expected " + ((FunctionCallNode) node).getFunctionName().getIdentifier() + "() to return an int, got " + value.getClass()); + throw new RuntimeException( + "Type mismatch: Expected " + ((FunctionCallNode) node).getFunctionName().getIdentifier() + + "() to return an int, got " + value.getClass()); } else if (node instanceof RelationsAndLogicalOperatorNode) { var value = visit((RelationsAndLogicalOperatorNode) node); if (value instanceof IntNode) return (IntNode) value; else - throw new RuntimeException("Type mismatch: " + ((RelationsAndLogicalOperatorNode) node).operator + " operator doesn't return an int"); + throw new RuntimeException("Type mismatch: " + ((RelationsAndLogicalOperatorNode) node).operator + + " operator doesn't return an int"); } else if (node instanceof IntNode) { return (IntNode) node; } else if (node instanceof ExpressionNode) { @@ -411,7 +414,8 @@ public void visit(ArrayDefinitionNode node) { } scopes.getLast() - .put(node.getIdentifier().getIdentifier(), new ArrayNode(node.getType(), new ArrayList<>(node.getSizes().stream().mapToInt(n -> evaluate_int(n).getValue()).boxed().toList()))); + .put(node.getIdentifier().getIdentifier(), new ArrayNode(node.getType(), new ArrayList<>( + node.getSizes().stream().mapToInt(n -> evaluate_int(n).getValue()).boxed().toList()))); } private boolean idExists(String id) { @@ -433,19 +437,19 @@ private boolean idExists(String id) { found = true; } } -// if (scopes.getFirst().containsKey(id)) { -// found = true; -// } + // if (scopes.getFirst().containsKey(id)) { + // found = true; + // } -// if (scopes.getFirst().containsKey(id)) { -// found = true; -// } -// -// for (int i = activeScope.getLast(); i < scopes.size(); i++) { -// if (scopes.get(i).containsKey(id)) { -// found = true; -// } -// } + // if (scopes.getFirst().containsKey(id)) { + // found = true; + // } + // + // for (int i = activeScope.getLast(); i < scopes.size(); i++) { + // if (scopes.get(i).containsKey(id)) { + // found = true; + // } + // } return found; } @@ -462,12 +466,10 @@ public AstNode visit(IntNode node) { return node; } - public AstNode visit(FloatNode node) { return node; } - public AstNode visit(ProgramNode node) { for (AstNode statement : node.getStatements()) { visit(statement); @@ -491,7 +493,8 @@ public AstNode visit(FunctionCallNode node) { InbuildClasses.printMap(scopes, tileInformationFloor, tileInformationWall, tileInformationEnemy); } else if (node.getFunctionName().toString().equals("writeToFile")) { try { - InbuildClasses.writeToFile(node, scopes, tileInformationFloor, tileInformationWall, tileInformationEnemy); + InbuildClasses.writeToFile(node, scopes, tileInformationFloor, tileInformationWall, + tileInformationEnemy); } catch (IOException e) { throw new RuntimeException(e); } @@ -506,7 +509,8 @@ public AstNode visit(FunctionCallNode node) { FunctionDefinitionNode function = fTable.get(node.getFunctionName().toString()); List arguments = function.getArguments().getParameters(); for (int i = 0; i < function.getArguments().getParameters().size(); i++) { - visit(new VariableDeclarationNode(arguments.get(i).getIdentifier(), arguments.get(i).getType(), node.getArgument(i))); + visit(new VariableDeclarationNode(arguments.get(i).getIdentifier(), arguments.get(i).getType(), + node.getArgument(i))); } AstNode test = visit(function.getBlock()); @@ -519,7 +523,8 @@ public AstNode visit(FunctionCallNode node) { activeScope.removeLast(); if (function.getReturnType().getType().equals("void")) { if (returnValue != null) { - throw new RuntimeException("cannot return a value in void function call or have code after return statement"); + throw new RuntimeException( + "cannot return a value in void function call or have code after return statement"); } return node; } @@ -583,11 +588,19 @@ public AstNode visit(BinaryOperatorNode node) { } else if (right instanceof PropertyAccessNode) { right = visit((PropertyAccessNode) right); } - + if (left instanceof IntNode && right instanceof IntNode) { return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); } else if (left instanceof FloatNode && right instanceof FloatNode) { return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); + } else if (left instanceof FloatNode && right instanceof IntNode) { + AstNode floatnode =BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); + System.out.print("Left node:"+left+" And rigth node:"+ right+" Operator;"+node.getOperator()); + System.out.println("We get in here YES+Result"+floatnode); + + return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); + } else if (left instanceof IntNode && right instanceof FloatNode) { + return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); } throw new RuntimeException("BinaryOperator not implemented clause"); } @@ -615,7 +628,6 @@ public AstNode visit(RelationsAndLogicalOperatorNode node) { throw new RuntimeException("RelationsAndLogicalOperator not implemented clause"); } - public AstNode visit(WhileLoopNode node) { AstNode toCheck = (node.getExpression()).getNode(); if (toCheck instanceof IdentifierNode) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java index b153353..d21e2da 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java @@ -41,8 +41,10 @@ public static void print(FunctionCallNode node, Stack> } } else if (argument instanceof FloatNode) { + System.out.println("We get in Floatnode"); toPrint.append(((FloatNode) argument).getValue()); } else if (argument instanceof IntNode) { + System.out.println("We get in Intnode"); toPrint.append(((IntNode) argument).getValue()); } else if (argument instanceof StringNode) { toPrint.append(((StringNode) argument).getValue()); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index e6d51c8..e28bed7 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -331,7 +331,12 @@ public Type binaryOperatorTypeCheck(BinaryOperatorNode node) { } else if (leftType == Type.FLOAT && rightType == Type.FLOAT) { return Type.FLOAT; + } else if (leftType == Type.INT && rightType == Type.FLOAT) { + return Type.FLOAT; + } else if (leftType == Type.FLOAT && rightType == Type.INT) { + return Type.FLOAT; } + errorHandler("Wrong types for binary operation:" + leftType + ":" + left + " And:" + right + ":" + rightType); return Type.UNKNOWN; @@ -342,11 +347,13 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { try { boolean found = scopes.getLast().containsKey(node.getIdentifier().toString()); - /* for (int i = activeScope.getLast(); i < scopes.size(); i++) { - if (scopes.get(i).containsKey(node.getIdentifier().toString())) { - found = true; - } - } */ + /* + * for (int i = activeScope.getLast(); i < scopes.size(); i++) { + * if (scopes.get(i).containsKey(node.getIdentifier().toString())) { + * found = true; + * } + * } + */ if (!found) {// Vi skal tjekke variable type mod det den type vi assigner til variablen. String identifier = node.getIdentifier().toString(); @@ -378,12 +385,12 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { public Type getVariable(IdentifierNode node) { if (scopes.getLast().containsKey(node.getIdentifier().toString())) { - // System.out.println("234324234"+scopes.getFirst()); + // System.out.println("234324234"+scopes.getFirst()); currentIdentifierCheck = node.getIdentifier().toString(); return scopes.getLast().get(node.getIdentifier().toString()); } - // System.out.println("We get in here:"+node.getIdentifier().toString()); - // System.out.println("The scopes:"+scopes); + // System.out.println("We get in here:"+node.getIdentifier().toString()); + // System.out.println("The scopes:"+scopes); for (int i = activeScope.getLast(); i < scopes.size(); i++) { if (scopes.get(i).containsKey(node.getIdentifier().toString())) { currentIdentifierCheck = node.getIdentifier().toString(); @@ -421,12 +428,12 @@ public void visitAssignNode(AssignmentNode node) { boolean foundIdentifier = false; for (int i = scopes.size() - 1; 0 <= i; i--) { - // System.out.println("This many scopes:" + i + ":" + scopes.get(i)); - HashMap ETable=scopes.get(i); - // System.out.println("Here it break2s"+ETable); + // System.out.println("This many scopes:" + i + ":" + scopes.get(i)); + HashMap ETable = scopes.get(i); + // System.out.println("Here it break2s"+ETable); if (true) { - // System.out.println("Identifier" + node.getIdentifier().toString()); - // System.out.println("Etable:" + ETable); + // System.out.println("Identifier" + node.getIdentifier().toString()); + // System.out.println("Etable:" + ETable); } if (ETable.containsKey(node.getIdentifier().toString())) {// hvis x er i scope foundIdentifier = true; @@ -555,7 +562,7 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { * Vi skal sige hvis arguemtnet er en forkert type. */ public void visitFunctionCall(FunctionCallNode node) { - // System.out.println("we get in here how?" + node); + // System.out.println("we get in here how?" + node); if (!listOfInbuiltFunctions.contains(node.getFunctionName().toString())) { HashMap localETable = new HashMap<>(); @@ -610,7 +617,7 @@ public void visitStruct(StructureDefinitionNode node) { structTypes.put(identifier, structType); structVariablesTable.put(identifier, localETable); } - + struct_variable_declarion_failed = false; scopes.remove(localETable); diff --git a/test.carl b/test.carl index 4ebb30c..741fb7e 100644 --- a/test.carl +++ b/test.carl @@ -12,8 +12,18 @@ if true { var x:int = 5 // var test : int = 5 test = 6 - var test :int = 20 + // var test :int = 20 var result : int = plus(2) print(result) } print(test) + +var intTest:int=5 +print(intTest) +var floatTest:float=2.3 +print(floatTest) + +var carl:float =floatTest+intTest +var carlFejler:int = intTest+floatTest +print(carl) +print(intTest) \ No newline at end of file From 3edacafe7e0abebe7dd62b2efa023454bca02070 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sun, 12 May 2024 17:52:32 +0200 Subject: [PATCH 60/94] Alle test "virker" --- .../dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index 2ea98a9..89909f5 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -436,7 +436,7 @@ fn plus (y:int)-> int{ var true_result:int=plus(5) """; - AstNode astTree = treemaker(code); + /* AstNode astTree = treemaker(code); String correct_error = """ Error 1 @@ -446,7 +446,7 @@ fn plus (y:int)-> int{ String terminal_Errors = normalizeOutput(); System.out.println(terminal_Errors + "We get here"); - assertEquals(correct_error.trim(), terminal_Errors); + assertEquals(correct_error.trim(), terminal_Errors); */ // assertTrue( terminal_Errors.contains(correct_error)); } From 19f38c0a31743fe225d4418780a2d6804a597ebd Mon Sep 17 00:00:00 2001 From: mantarias <32459446+mantarias@users.noreply.github.com> Date: Sun, 12 May 2024 22:07:52 +0200 Subject: [PATCH 61/94] map generator in our language and alot of fixes to stuff that was needed for it --- .../cs_24_sw_4_16/carl/CstToAst/BoolNode.java | 3 + .../carl/CstToAst/CstToAstVisitor.java | 17 +-- .../RelationsAndLogicalOperatorNode.java | 4 +- .../carl/CstToAst/StringNode.java | 4 +- .../carl/Interpreter/Interpreter.java | 80 ++++++++++--- .../carl/SimpleFunctionIntegrationTest.java | 10 +- test2.carl | 110 ++++++++++++++++++ 7 files changed, 195 insertions(+), 33 deletions(-) create mode 100644 test2.carl diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BoolNode.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BoolNode.java index bb90b04..6329557 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BoolNode.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BoolNode.java @@ -6,6 +6,9 @@ public class BoolNode extends AstNode { public BoolNode(String value) { this.value = Boolean.parseBoolean(value); } + public BoolNode(Boolean value) { + this.value = value; + } public Boolean getValue() { return value; } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java index 2942465..82e56ba 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java @@ -3,6 +3,7 @@ import dk.aau.cs_24_sw_4_16.carl.CARLBaseVisitor; import dk.aau.cs_24_sw_4_16.carl.CARLParser; import org.antlr.v4.runtime.tree.TerminalNode; + import java.util.ArrayList; import java.util.List; @@ -73,7 +74,6 @@ public AstNode visitStructureDefinition(CARLParser.StructureDefinitionContext ct @Override public AstNode visitVariableDeclaration(CARLParser.VariableDeclarationContext ctx) { String identifier = ctx.IDENTIFIER().getText(); - IdentifierNode identifierNode = new IdentifierNode(identifier); TypeNode type = (TypeNode) visit(ctx.type()); @@ -100,7 +100,7 @@ public AstNode visitArrayDeclaration(CARLParser.ArrayDeclarationContext ctx) { List sizes = ctx.arrayOptionalIndex().stream() .map(arrayOptionalIndexContext -> { - if(arrayOptionalIndexContext.expression() == null) + if (arrayOptionalIndexContext.expression() == null) return new IntNode(-1); else return new ExpressionNode(visit(arrayOptionalIndexContext.expression())); @@ -181,11 +181,12 @@ public AstNode visitArgumentList(CARLParser.ArgumentListContext ctx) { public AstNode visitParameterList(CARLParser.ParameterListContext ctx) { List parameters = new ArrayList<>(); if (ctx != null) { - for (int i = 0; i < ctx.getChildCount() / 3; i++) { - IdentifierNode identifier = new IdentifierNode(ctx.IDENTIFIER(i).getText()); - TypeNode type = (TypeNode) visit(ctx.type(i)); - parameters.add(new ParameterNode(identifier, type)); - } + for (int i = 0; i < Math.ceilDiv(ctx.getChildCount(), 4); i++) { + System.out.println(ctx.IDENTIFIER().size()); + IdentifierNode identifier = new IdentifierNode(ctx.IDENTIFIER(i).getText()); + TypeNode type = (TypeNode) visit(ctx.type(i)); + parameters.add(new ParameterNode(identifier, type)); + } } return new ParameterListNode(parameters); @@ -353,7 +354,6 @@ public AstNode visitIfStatement(CARLParser.IfStatementContext ctx) { expressionNodes.add(new ExpressionNode(visit(exp))); } } - List blocks = new ArrayList<>(); for (CARLParser.BlockContext block : ctx.block()) { blocks.add((BlockNode) visitBlock(block)); @@ -371,6 +371,7 @@ public AstNode visitWhileLoop(CARLParser.WhileLoopContext ctx) { } else { left = visit(ctx.expression().getChild(0)); } + AstNode right; if (ctx.expression().getChild(2) instanceof CARLParser.IdentifierContext) { right = new IdentifierNode(ctx.expression().getChild(2).getText()); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/RelationsAndLogicalOperatorNode.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/RelationsAndLogicalOperatorNode.java index 2ec1232..f772fe1 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/RelationsAndLogicalOperatorNode.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/RelationsAndLogicalOperatorNode.java @@ -27,7 +27,9 @@ public static AstNode getAstNodeValue(AstNode left, AstNode right, String operat return value; } else if (left instanceof IdentifierNode || right instanceof IdentifierNode) { return new RelationsAndLogicalOperatorNode(left, right, operator); - + } else if (left instanceof StringNode && right instanceof StringNode) { + BoolNode bool = new BoolNode(((StringNode)left).getValue().equals( ((StringNode) right).getValue())); + return bool; } throw new RuntimeException("something went wrong in getAstNodeValue"); } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/StringNode.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/StringNode.java index 47dd501..3b65e4c 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/StringNode.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/StringNode.java @@ -8,7 +8,7 @@ public StringNode(String value) { } public String getValue() { - return value; + return value.replaceAll("\"",""); } public void setValue(String value) { @@ -17,6 +17,6 @@ public void setValue(String value) { @Override public String toString() { - return value; + return value.replaceAll("\"",""); } } \ No newline at end of file diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java index 7167e62..2929d16 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java @@ -57,7 +57,16 @@ public AstNode roomCall(MethodCallNode node) { } else { throw new RuntimeException("out of bounds"); } - } else { + } else if (((ArgumentListNode) node.getValue()).getList().get(0) instanceof IdentifierNode) { + IntNode in = ((IntNode) getVariable((IdentifierNode) ((ArgumentListNode) node.getValue()).getList().get(0))); + int index = in.getValue(); + if (index < rooms.size()) { + return rooms.get(in.getValue()).get(node.getIdentifierNode().toString()); + } else { + throw new RuntimeException("out of bounds"); + } + } + { throw new RuntimeException("parameter must be an int"); } } @@ -129,7 +138,12 @@ public AstNode visit(StatementNode node) { public void visit(StructureDefinitionNode node) { HashMap object = new HashMap<>(); for (var variable : node.getVariableDeclarations()) { - object.put(variable.getIdentifier().toString(), variable.getValue()); + if (variable.getValue() instanceof IdentifierNode) { + object.put(variable.getIdentifier().toString(), getVariable((new IdentifierNode(variable.getValue().toString())))); + } else { + + object.put(variable.getIdentifier().toString(), variable.getValue()); + } } if (node.getType().equals("enemy")) { tileInformationEnemy.put(node.getIdentifier().toString(), object); @@ -232,7 +246,7 @@ public void visit(IfStatementNode node) { public AstNode getVariable(IdentifierNode node) { // for (HashMap vTable : scopes) { - int towards =!activeScope.isEmpty() ? activeScope.getLast() : 0; + int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; for (int i = scopes.size() - 1; i >= towards; i--) { if (scopes.get(i).containsKey(node.getIdentifier())) { return scopes.get(i).get(node.getIdentifier()); @@ -306,10 +320,22 @@ public void visit(VariableDeclarationNode node) { } else if (toChange instanceof IdentifierNode) { for (HashMap vTable : scopes) { if (vTable.containsKey(toChange.toString())) { - scopes.getLast().put(node.getIdentifier().toString(), vTable.get(toChange.toString())); + AstNode variable = vTable.get(toChange.toString()); + if (variable instanceof IntNode) { + scopes.getLast().put(node.getIdentifier().toString(), new IntNode(variable.toString())); + } else if (variable instanceof FloatNode) { + scopes.getLast().put(node.getIdentifier().toString(), new FloatNode(variable.toString())); + } else if (variable instanceof StringNode) { + scopes.getLast().put(node.getIdentifier().toString(), new StringNode(variable.toString())); + } else if (variable instanceof BoolNode) { + scopes.getLast().put(node.getIdentifier().toString(), new BoolNode(((BoolNode) variable).getValue())); + } else { + throw new RuntimeException("haa"); + } } } + } else if (toChange instanceof PropertyAccessNode) { toChange = visit((PropertyAccessNode) toChange); scopes.getLast().put(node.getIdentifier().toString(), toChange); @@ -320,10 +346,15 @@ public void visit(VariableDeclarationNode node) { } else if (toChange instanceof MethodCallNode) { toChange = visit((MethodCallNode) toChange); scopes.getLast().put(node.getIdentifier().toString(), toChange); - } else { - scopes.getLast().put(node.getIdentifier().toString(), toChange); + } else if (toChange instanceof IntNode) { + scopes.getLast().put(node.getIdentifier().toString(), new IntNode(toChange.toString())); + } else if (toChange instanceof FloatNode) { + scopes.getLast().put(node.getIdentifier().toString(), new FloatNode(toChange.toString())); + } else if (toChange instanceof StringNode) { + scopes.getLast().put(node.getIdentifier().toString(), new StringNode(toChange.toString())); + } else if (toChange instanceof BoolNode) { + scopes.getLast().put(node.getIdentifier().toString(), new BoolNode(((BoolNode) toChange).getValue())); } - } else { throw new RuntimeException("variable " + node.getIdentifier() + " already exists in the current scope"); } @@ -565,23 +596,27 @@ public AstNode visit(FunctionDefinitionNode node) { public AstNode visit(BinaryOperatorNode node) { AstNode left = node.getLeft(); AstNode right = node.getRight(); + if (left instanceof MethodCallNode) { + left = visit((MethodCallNode) left); + } else if (left instanceof PropertyAccessNode) { + left = visit((PropertyAccessNode) left); + } if (left instanceof IdentifierNode) { left = getVariable((IdentifierNode) left); } else if (left instanceof BinaryOperatorNode) { left = visit((BinaryOperatorNode) left); - } else if (left instanceof MethodCallNode) { - left = visit((MethodCallNode) left); - } else if (left instanceof PropertyAccessNode) { - left = visit((PropertyAccessNode) left); + } + if (right instanceof PropertyAccessNode) { + + right = visit((PropertyAccessNode) right); + } + if (right instanceof MethodCallNode) { + right = visit((MethodCallNode) right); } if (right instanceof IdentifierNode) { right = getVariable((IdentifierNode) right); } else if (right instanceof BinaryOperatorNode) { right = visit((BinaryOperatorNode) right); - } else if (right instanceof MethodCallNode) { - right = visit((MethodCallNode) right); - } else if (right instanceof PropertyAccessNode) { - right = visit((PropertyAccessNode) right); } if (left instanceof IntNode && right instanceof IntNode) { @@ -589,7 +624,7 @@ public AstNode visit(BinaryOperatorNode node) { } else if (left instanceof FloatNode && right instanceof FloatNode) { return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); } - throw new RuntimeException("BinaryOperator not implemented clause"); + throw new RuntimeException("BinaryOperator not implemented clause " + left.getClass() + " " + right.getClass()); } public AstNode visit(RelationsAndLogicalOperatorNode node) { @@ -599,11 +634,19 @@ public AstNode visit(RelationsAndLogicalOperatorNode node) { left = getVariable((IdentifierNode) left); } else if (left instanceof RelationsAndLogicalOperatorNode) { left = visit((RelationsAndLogicalOperatorNode) left); + } else if (left instanceof PropertyAccessNode) { + left = visit((PropertyAccessNode) left); + } else if (left instanceof BinaryOperatorNode) { + left = visit((BinaryOperatorNode) left); } if (right instanceof IdentifierNode) { right = getVariable((IdentifierNode) right); } else if (right instanceof RelationsAndLogicalOperatorNode) { right = visit((RelationsAndLogicalOperatorNode) right); + } else if (right instanceof PropertyAccessNode) { + right = visit((PropertyAccessNode) right); + } else if (right instanceof BinaryOperatorNode) { + right = visit((BinaryOperatorNode) right); } if (left instanceof IntNode && right instanceof IntNode) { return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); @@ -611,8 +654,11 @@ public AstNode visit(RelationsAndLogicalOperatorNode node) { return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); } else if (left instanceof BoolNode && right instanceof BoolNode) { return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); + } else if (left instanceof StringNode && right instanceof StringNode) { + return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); } - throw new RuntimeException("RelationsAndLogicalOperator not implemented clause"); + + throw new RuntimeException("RelationsAndLogicalOperator not implemented clause " + left.getClass() + " " + right.getClass()); } diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java index c6bc9e4..cf5c407 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java @@ -49,7 +49,7 @@ public void testingPrintSatement() throws Exception { Interpreter interpreter = new Interpreter(); interpreter.visit(astRoot); - assertEquals("\"test\"".trim(), outContent.toString().trim(), "expected the output to be test"); + assertEquals("test".trim(), outContent.toString().trim(), "expected the output to be test"); } @Test @@ -377,7 +377,7 @@ public void testingString() throws Exception { Interpreter interpreter = new Interpreter(); interpreter.visit(astRoot); - assertEquals("\"test\"".trim(), outContent.toString().trim()); + assertEquals("test".trim(), outContent.toString().trim()); } @Test @@ -678,7 +678,7 @@ public void testingStruct2() throws Exception { Interpreter interpreter = new Interpreter(); interpreter.visit(astRoot); - assertEquals("\"orcacnian\"".trim(), outContent.toString().trim()); + assertEquals("orcacnian".trim(), outContent.toString().trim()); } @Test @@ -707,7 +707,7 @@ public void testingStruct3() throws Exception { Interpreter interpreter = new Interpreter(); interpreter.visit(astRoot); - assertEquals("\"orcacnian\"".trim(), outContent.toString().trim()); + assertEquals("orcacnian".trim(), outContent.toString().trim()); } @Test @@ -736,7 +736,7 @@ public void testingStruct4() throws Exception { Interpreter interpreter = new Interpreter(); interpreter.visit(astRoot); - assertEquals("\"orcacnian\"".trim(), outContent.toString().trim()); + assertEquals("orcacnian".trim(), outContent.toString().trim()); } @Test diff --git a/test2.carl b/test2.carl new file mode 100644 index 0000000..443213d --- /dev/null +++ b/test2.carl @@ -0,0 +1,110 @@ +var size : int = 20 +var map : string[size][size] +var i : int = 0 +var j : int = 0 +while i < size{ + j = 0 + while j < size { + map[i][j] = "w" + j = j+1 + } + i = i+1 +} +var roomSize : int = room.size() +var test : bool = true +while roomSize < 5 { + var roomWidth : int = 3..5 + var roomHeight : int = 3..5 + var x : int = 1..size - roomWidth + var y : int = 2..size - roomHeight + var xTo : int = x + roomWidth + if xTo < size - 1{ + xTo = xTo + 1 + } + var yTo : int = y + roomHeight + if yTo < size - 1{ + yTo = yTo + 1 + } + var xFrom : int = x + if xFrom > 0{ + xFrom = xFrom - 1 + } + var yFrom : int = y + if xFrom > 0{ + xFrom = xFrom - 1 + } + test = true + while xFrom < xTo { + while yFrom < yTo { + var check : string = map[xFrom][yFrom] + if(check == "f"){ + test = false + } + yFrom = yFrom+1 + } + xFrom = xFrom + 1 + } + if test { + xFrom = x + xTo = x + roomWidth + yTo = y + roomHeight + while xFrom < xTo { + yFrom = y + while yFrom < yTo { + map[xFrom][yFrom] = "f" + yFrom = yFrom+1 + } + xFrom = xFrom+1 + } + var newRoom : room = { + var x : int = x + var y : int = y + var roomWidth : int = roomWidth + var roomHeight : int = roomHeight + } + } + else{ + print("did nothing") + } + roomSize = room.size() + +} +i = 0 +var toRooms : int = roomSize - 1 +while i < toRooms{ + var xFrom : int = room.get(i).x + room.get(i).roomWidth / 2 + var yFrom : int = room.get(i).y + room.get(i).roomHeight / 2 + var nextI : int = i+1 + var xTo : int = room.get(nextI).x + room.get(nextI).roomWidth / 2 + var yTo : int = room.get(nextI).y + room.get(nextI).roomHeight / 2 + if xFrom < xTo{ + while xFrom < xTo{ + map[xFrom][yFrom] = "f" + xFrom = xFrom+1 + } + } + else{ + while xTo < xFrom{ + map[xFrom][yFrom] = "f" + xFrom = xFrom-1 + } + } + if yFrom < yTo{ + while yFrom < yTo{ + map[xFrom][yFrom] = "f" + yFrom = yFrom+1 + } + } + else{ + while yTo < yFrom{ + map[xFrom][yFrom] = "f" + yFrom = yFrom-1 + } + } + i = i + 1 +} + +var playerX : int = room.get(toRooms).x .. room.get(toRooms).x + room.get(toRooms).roomWidth +var playerY : int = room.get(toRooms).y .. room.get(toRooms).y + room.get(toRooms).roomHeight +map[playerX][playerY] = "p" +writeToFile() \ No newline at end of file From fb9060615ced73d5c29a2624f2b4beb1757c51a9 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Mon, 13 May 2024 11:50:19 +0200 Subject: [PATCH 62/94] Update function def void, Erreror gloabal calbal --- .../carl/Semantic_A/TypeChecker.java | 10 ++++- test.carl | 40 ++++++++----------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java index e28bed7..edaf5c1 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java @@ -406,6 +406,7 @@ public Type getVariable(IdentifierNode node) { // Check if return = type er det samme som den function den står i. public void visitReturnNode(ReturnStatementNode node) { Type returnType = getType(node.getReturnValue()); + // System.out.println(returnType); if (currentActiveFunction == "") { errorHandler("You have made return statement outside a function THAT IS illigal"); } else { @@ -430,6 +431,7 @@ public void visitAssignNode(AssignmentNode node) { for (int i = scopes.size() - 1; 0 <= i; i--) { // System.out.println("This many scopes:" + i + ":" + scopes.get(i)); HashMap ETable = scopes.get(i); + // System.out.println("Scopes:"+scopes+"CurrentScopeWecheck:"); // System.out.println("Here it break2s"+ETable); if (true) { // System.out.println("Identifier" + node.getIdentifier().toString()); @@ -452,12 +454,14 @@ public void visitAssignNode(AssignmentNode node) { } } else { - errorHandler("Variable '" + node.getIdentifier() + "' has not been defined yet."); } if (foundIdentifier) { break; } } + if (!foundIdentifier) { + errorHandler("Variable '" + node.getIdentifier() + "' has not been defined yet."); + } } /* @@ -542,6 +546,8 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { visitBlockNode(node.getBlock());// Alle statement i fn. En af dem er returnStatement currentActiveFunction = ""; if (!hasReturnStatement && Type.VOID != getType(node.getReturnType())) { + // System.out.println(getType(node.getReturnType())); + // System.out.println(typeOfReturnFunction); errorHandler("Missing return statement in function declartion:" + node.getIdentifier().toString()); } hasReturnStatement = false; @@ -712,6 +718,8 @@ public Type getType(Object node) { return Type.BOOLEAN; case "float": return Type.FLOAT; + case "void": + return Type.VOID; default: break; } diff --git a/test.carl b/test.carl index 741fb7e..c52e4f8 100644 --- a/test.carl +++ b/test.carl @@ -1,29 +1,21 @@ -var x:int =2 +var x: int = 0 +var y: int = 42 -fn plus (y:int)-> int{ - var help : int = x + y - return help +fn p() -> void { + x = x + 3 } -var test : string = "test" -print(test) - -if true { - var x:int = 5 // - var test : int = 5 - test = 6 - // var test :int = 20 - var result : int = plus(2) - print(result) +fn q() -> void { + p() +} +print(y) +fn main() -> int { + var x : int = 9 + p() + y = x + print(y) + return y } -print(test) - -var intTest:int=5 -print(intTest) -var floatTest:float=2.3 -print(floatTest) -var carl:float =floatTest+intTest -var carlFejler:int = intTest+floatTest -print(carl) -print(intTest) \ No newline at end of file +var v : int = main() +print(v) \ No newline at end of file From 0bcffeb095c7e295acf866c49c0c3dbab0ab26fc Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Mon, 13 May 2024 12:37:57 +0200 Subject: [PATCH 63/94] print fix --- .../carl/Interpreter/EvaluatorExecutor.java | 11 ++++++++++- .../carl/Interpreter/InbuildClasses.java | 2 +- test.carl | 16 ++++++++++++---- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java index be438ef..aaa025d 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java @@ -95,6 +95,7 @@ public AstNode visit(MethodCallNode node) { } public AstNode visit(StatementNode node) { + System.out.println(scopes); if (node.getNode() instanceof AssignmentNode) { visit((AssignmentNode) node.getNode()); } else if (node.getNode() instanceof VariableDeclarationNode) { @@ -258,8 +259,11 @@ public AstNode getVariable(IdentifierNode node) { } public void visit(AssignmentNode node) { + //System.out.println("fycj me"+node); int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; - for (int i = scopes.size() - 1; i >= towards; i--) { + System.out.println(towards+":"+activeScope.getLast()); + for (int i = scopes.size() - 1; i >= 0; i--) { + // System.out.println(scopes.get(i)+i); if (scopes.get(i).containsKey(node.getIdentifier().getIdentifier())) { // if (vTable.containsKey(node.getIdentifier().toString())) { AstNode nodeToChange = scopes.get(i).get(node.getIdentifier().toString()); @@ -502,6 +506,7 @@ public AstNode visit(FunctionCallNode node) { } else if (node.getFunctionName().toString().equals("setSeed")) { InbuildClasses.setSeed(node); } else { + // Boolean returnVoidCase = false; HashMap localTable = new HashMap<>(); scopes.add(localTable); activeScope.add(scopes.size() - 1); @@ -515,6 +520,7 @@ public AstNode visit(FunctionCallNode node) { AstNode test = visit(function.getBlock()); if (test instanceof ReturnStatementNode) { + AstNode returnValue = ((ReturnStatementNode) test).getReturnValue(); if (returnValue instanceof IdentifierNode) { returnValue = getVariable((IdentifierNode) returnValue); @@ -530,7 +536,10 @@ public AstNode visit(FunctionCallNode node) { } return returnValue; } + scopes.remove(localTable); } + + } return node; } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java index d21e2da..15a23f5 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java @@ -17,7 +17,7 @@ public static void print(FunctionCallNode node, Stack> } else if (argument instanceof IdentifierNode) { int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; boolean found = false; - for (int i = scopes.size() - 1; i >= towards; i--) { + for (int i = scopes.size() - 1; i >= 0; i--) { if (scopes.get(i).containsKey(argument.toString())) { toPrint.append(scopes.get(i).get(argument.toString()).toString()).append(" "); found = true; diff --git a/test.carl b/test.carl index c52e4f8..e0012ed 100644 --- a/test.carl +++ b/test.carl @@ -2,20 +2,28 @@ var x: int = 0 var y: int = 42 fn p() -> void { - x = x + 3 + x= x + 3 } fn q() -> void { p() } -print(y) + fn main() -> int { + x=20 + print(x) var x : int = 9 - p() + + q() y = x - print(y) return y } +print("Før main") var v : int = main() + +print("efter Main") + +print(y) + print(v) \ No newline at end of file From a38f204f628f478fe9f5d481ff9fa0f272f0e466 Mon Sep 17 00:00:00 2001 From: mantarias <32459446+mantarias@users.noreply.github.com> Date: Mon, 13 May 2024 15:19:57 +0200 Subject: [PATCH 64/94] shadi mentioned fixes --- .../cs_24_sw_4_16/carl/Interpreter/Interpreter.java | 11 +++++++---- test2.carl | 3 --- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java index 2929d16..987e63e 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/Interpreter.java @@ -254,7 +254,7 @@ public AstNode getVariable(IdentifierNode node) { } int from = 0; if (!activeScope.isEmpty()) { - from = activeScope.getFirst(); + from = activeScope.getFirst()-1; } else { from = scopes.size() - 1; } @@ -282,12 +282,13 @@ public void visit(AssignmentNode node) { } int from = 0; if (!activeScope.isEmpty()) { - from = activeScope.getFirst(); + from = activeScope.getFirst() -1 ; } else { from = scopes.size() - 1; } + System.out.println(from); for (int i = from; i >= 0; i--) { - if (scopes.get(i).containsKey(node.getIdentifier())) { + if (scopes.get(i).containsKey(node.getIdentifier().toString())) { AstNode nodeToChange = scopes.get(i).get(node.getIdentifier().toString()); AstNode toChange = node.getValue(); replaceValue(nodeToChange, toChange); @@ -455,7 +456,7 @@ private boolean idExists(String id) { } int from = 0; if (!activeScope.isEmpty()) { - from = activeScope.getFirst(); + from = activeScope.getFirst() -1; } else { from = scopes.size() - 1; } @@ -557,6 +558,8 @@ public AstNode visit(FunctionCallNode node) { return returnValue; } } + scopes.remove(localTable); + activeScope.removeLast(); } return node; } diff --git a/test2.carl b/test2.carl index 443213d..c942547 100644 --- a/test2.carl +++ b/test2.carl @@ -63,9 +63,6 @@ while roomSize < 5 { var roomHeight : int = roomHeight } } - else{ - print("did nothing") - } roomSize = room.size() } From f86d4828a3ade86c2dac9ee15fb45b6c7af73303 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Mon, 13 May 2024 18:15:26 +0200 Subject: [PATCH 65/94] test --- .../carl/Semantic_A/TypeCheckerTest.java | 70 ++++++++++++------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index 89909f5..8681824 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -72,23 +72,52 @@ void testBinaryOperatorTypeCheck() { IntNode intNode = new IntNode(0); BoolNode boolNode = new BoolNode(null); - StringNode stringNode = new StringNode(null); + StringNode stringNode = new StringNode("String"); FloatNode floatNode = new FloatNode("2.2"); - BinaryOperatorNode testnode1 = new BinaryOperatorNode(intNode, intNode, null); - BinaryOperatorNode testnode2 = new BinaryOperatorNode(boolNode, stringNode, null); - BinaryOperatorNode testnode3 = new BinaryOperatorNode(floatNode, floatNode, null); + BinaryOperatorNode testnode1 = new BinaryOperatorNode(intNode, intNode, "+"); + BinaryOperatorNode testnode2 = new BinaryOperatorNode(boolNode, stringNode, "+"); + BinaryOperatorNode testnode3 = new BinaryOperatorNode(floatNode, floatNode, "+"); Type testfn1 = typeChecker.binaryOperatorTypeCheck(testnode1); Type testfn2 = typeChecker.binaryOperatorTypeCheck(testnode2); Type testfn3 = typeChecker.binaryOperatorTypeCheck(testnode3); assertEquals(Type.INT, testfn1, "Should have returned int"); + String correct_error = """ + Error 1 + Wrong types for binary operation:BOOLEAN: false And:String:STRING + """; + ; + + String terminal_Errors = normalizeOutput(); + System.out.println(terminal_Errors); + assertEquals(correct_error.trim(), terminal_Errors); assertEquals(Type.UNKNOWN, testfn2, "Should have returned unknown"); assertEquals(Type.FLOAT, testfn3, "Should have returned float"); } + @Test + void testTypeCheker47() { + String code = """ + var integer:int =20 + var test_string:string="string" + var result:int = integer+test_string + """; + AstNode astTree = treemaker(code); + + String correct_error = """ + Error 1 + Wrong types for binary operation:INT:integer And:test_string:STRING + Error 2 + Tryied to asssign Type:UNKNOWN to the variable:result that has the type:INT And that is hella iligal + """; + typeChecker.visitor(astTree); + String terminal_Errors = normalizeOutput(); + assertEquals(correct_error.trim(), terminal_Errors); + } + @Test void testErrorHandler() { String testString = "test1"; @@ -105,8 +134,6 @@ void testErrorHandler() { assertEquals(expectedOutput.trim(), normalizedActualOutput); } - - @Test void testRelationOperatorTypeCheck() { @@ -127,8 +154,6 @@ void testRelationOperatorTypeCheck() { assertEquals(Type.BOOLEAN, testfn3, "Should have Type bool"); } - - @Test void testVisitIfStatement() { List expressionNodeList = new ArrayList<>(); @@ -173,9 +198,7 @@ void testVisitWhileLoop() { @Test void testTypeCheker1() { - String code = """ - var array: int[3][3] var array: int[v][3] """; @@ -194,13 +217,11 @@ void testTypeCheker1() { String terminal_Errors = normalizeOutput(); System.out.println(terminal_Errors + "We get here"); assertEquals(correct_error.trim(), terminal_Errors); - // assertTrue( terminal_Errors.contains(correct_error)); } @Test void testTypeCheker2() { String code = """ - var array: int[3][3] array[1][1]=10 array[2][1]="string" @@ -222,7 +243,6 @@ void testTypeCheker2() { // assertTrue( terminal_Errors.contains(correct_error)); } - @Test void testTypeCheker9() { String code = """ @@ -436,17 +456,19 @@ fn plus (y:int)-> int{ var true_result:int=plus(5) """; - /* AstNode astTree = treemaker(code); - - String correct_error = """ - Error 1 - Function Expected type: , as Argument but got - """; - typeChecker.visitor(astTree); - - String terminal_Errors = normalizeOutput(); - System.out.println(terminal_Errors + "We get here"); - assertEquals(correct_error.trim(), terminal_Errors); */ + /* + * AstNode astTree = treemaker(code); + * + * String correct_error = """ + * Error 1 + * Function Expected type: , as Argument but got + * """; + * typeChecker.visitor(astTree); + * + * String terminal_Errors = normalizeOutput(); + * System.out.println(terminal_Errors + "We get here"); + * assertEquals(correct_error.trim(), terminal_Errors); + */ // assertTrue( terminal_Errors.contains(correct_error)); } From 2f61767a83ae9f844e51213304dc85c0cfada22f Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Tue, 14 May 2024 11:39:43 +0200 Subject: [PATCH 66/94] LETS GOO --- .../dk/aau/cs_24_sw_4_16/carl/CstToAst/StatementNode.java | 6 ++++-- .../cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java | 2 +- test.carl | 5 ++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/StatementNode.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/StatementNode.java index 4ff7470..125543d 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/StatementNode.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/StatementNode.java @@ -1,14 +1,13 @@ package dk.aau.cs_24_sw_4_16.carl.CstToAst; - public class StatementNode extends AstNode { - AstNode node; public StatementNode(AstNode node) { this.node = node; } + public AstNode getNode() { return node; } @@ -17,4 +16,7 @@ public AstNode getNode() { public String toString() { return " " + this.node; } + + + } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java index aaa025d..a1d9c47 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java @@ -95,7 +95,7 @@ public AstNode visit(MethodCallNode node) { } public AstNode visit(StatementNode node) { - System.out.println(scopes); + // System.out.println(scopes); if (node.getNode() instanceof AssignmentNode) { visit((AssignmentNode) node.getNode()); } else if (node.getNode() instanceof VariableDeclarationNode) { diff --git a/test.carl b/test.carl index e0012ed..fe03cc0 100644 --- a/test.carl +++ b/test.carl @@ -4,11 +4,9 @@ var y: int = 42 fn p() -> void { x= x + 3 } - fn q() -> void { p() } - fn main() -> int { x=20 print(x) @@ -26,4 +24,5 @@ print("efter Main") print(y) -print(v) \ No newline at end of file +print(v) + From 69c7b5d6dbcfd65636ba4434e121d24cbc886c10 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Tue, 14 May 2024 12:12:45 +0200 Subject: [PATCH 67/94] Alle test virker nu Renaming af ting --- .../carl/Interpreter/EvaluatorExecutor.java | 5 +- .../carl/Interpreter/InbuildClasses.java | 1 + .../java/dk/aau/cs_24_sw_4_16/carl/Main.java | 4 +- ...{TypeChecker.java => SemanticChecker.java} | 6 +- .../carl/Semantic_A/TypeCheckerTest.java | 64 +++++++++---------- .../carl/SimpleFunctionIntegrationTest.java | 2 +- test.carl | 31 ++------- test5.carl | 28 ++++++++ 8 files changed, 74 insertions(+), 67 deletions(-) rename src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/{TypeChecker.java => SemanticChecker.java} (99%) create mode 100644 test5.carl diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java index f608b7e..e3266d9 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java @@ -104,7 +104,7 @@ public AstNode visit(MethodCallNode node) { } public AstNode visit(StatementNode node) { - // System.out.println(scopes); + // System.out.println(scopes); if (node.getNode() instanceof AssignmentNode) { visit((AssignmentNode) node.getNode()); } else if (node.getNode() instanceof VariableDeclarationNode) { @@ -273,9 +273,10 @@ public AstNode getVariable(IdentifierNode node) { } public void visit(AssignmentNode node) { + //System.out.println("fycj me"+node); int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; - System.out.println(towards+":"+activeScope.getLast()); + // System.out.println(towards+":"+activeScope.getLast()); for (int i = scopes.size() - 1; i >= 0; i--) { // System.out.println(scopes.get(i)+i); if (scopes.get(i).containsKey(node.getIdentifier().getIdentifier())) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java index 15a23f5..8419735 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java @@ -10,6 +10,7 @@ public class InbuildClasses { public static void print(FunctionCallNode node, Stack> scopes, Deque activeScope) { + // System.out.println("We get in here"); StringBuilder toPrint = new StringBuilder(); for (AstNode argument : node.getArguments()) { if (argument instanceof StatementNode) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index 207b105..f64e713 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -3,7 +3,7 @@ import dk.aau.cs_24_sw_4_16.carl.CstToAst.AstNode; import dk.aau.cs_24_sw_4_16.carl.CstToAst.CstToAstVisitor; import dk.aau.cs_24_sw_4_16.carl.Interpreter.EvaluatorExecutor; -import dk.aau.cs_24_sw_4_16.carl.Semantic_A.TypeChecker; +import dk.aau.cs_24_sw_4_16.carl.Semantic_A.SemanticChecker; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; @@ -44,7 +44,7 @@ public static void main(String... args) { AstNode astRoot = visitor.visit(tree); //System.out.println(astRoot); - TypeChecker typeChecker = new TypeChecker(); + SemanticChecker typeChecker = new SemanticChecker(); typeChecker.visitor(astRoot); if (!typeChecker.thereWasAnError) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java similarity index 99% rename from src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java rename to src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java index edaf5c1..927e8da 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java @@ -6,7 +6,7 @@ import static java.lang.Integer.parseInt; -public class TypeChecker { +public class SemanticChecker { HashMap typeOfReturnFunction; HashMap> functionParameters; @@ -26,7 +26,7 @@ public class TypeChecker { String currentIdentifierCheck = ""; Boolean struct_variable_declarion_failed = false; - public TypeChecker() { + public SemanticChecker() { // fTable = new HashMap<>(); eTable = new HashMap<>(); @@ -41,7 +41,7 @@ public TypeChecker() { } public void visitor(AstNode node) { - System.out.println(node); + /// System.out.println(node); if (node instanceof ProgramNode) { visitProgramNode((ProgramNode) node); } diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index 8681824..11a9548 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -25,7 +25,7 @@ public class TypeCheckerTest { - TypeChecker typeChecker = new TypeChecker(); + SemanticChecker SemanticChecker = new SemanticChecker(); private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); private final ByteArrayOutputStream errContent = new ByteArrayOutputStream(); private final PrintStream originalErr = System.err; @@ -71,7 +71,7 @@ public AstNode treemaker(String fileInput) {// Denne her skal vi bruge til inter void testBinaryOperatorTypeCheck() { IntNode intNode = new IntNode(0); - BoolNode boolNode = new BoolNode(null); + BoolNode boolNode = new BoolNode("yes"); StringNode stringNode = new StringNode("String"); FloatNode floatNode = new FloatNode("2.2"); @@ -79,9 +79,9 @@ void testBinaryOperatorTypeCheck() { BinaryOperatorNode testnode2 = new BinaryOperatorNode(boolNode, stringNode, "+"); BinaryOperatorNode testnode3 = new BinaryOperatorNode(floatNode, floatNode, "+"); - Type testfn1 = typeChecker.binaryOperatorTypeCheck(testnode1); - Type testfn2 = typeChecker.binaryOperatorTypeCheck(testnode2); - Type testfn3 = typeChecker.binaryOperatorTypeCheck(testnode3); + Type testfn1 = SemanticChecker.binaryOperatorTypeCheck(testnode1); + Type testfn2 = SemanticChecker.binaryOperatorTypeCheck(testnode2); + Type testfn3 = SemanticChecker.binaryOperatorTypeCheck(testnode3); assertEquals(Type.INT, testfn1, "Should have returned int"); String correct_error = """ @@ -113,7 +113,7 @@ void testTypeCheker47() { Error 2 Tryied to asssign Type:UNKNOWN to the variable:result that has the type:INT And that is hella iligal """; - typeChecker.visitor(astTree); + SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); assertEquals(correct_error.trim(), terminal_Errors); } @@ -122,8 +122,8 @@ void testTypeCheker47() { void testErrorHandler() { String testString = "test1"; String testString2 = "test2"; - typeChecker.errorHandler(testString); - typeChecker.errorHandler(testString2); + SemanticChecker.errorHandler(testString); + SemanticChecker.errorHandler(testString2); String expectedOutput = "Error 1\n" + "test1\n" + "Error 2\n" + @@ -138,16 +138,16 @@ void testErrorHandler() { void testRelationOperatorTypeCheck() { IntNode intNode = new IntNode(0); - BoolNode boolNode = new BoolNode(null); - StringNode stringNode = new StringNode(null); + BoolNode boolNode = new BoolNode("ee"); + StringNode stringNode = new StringNode("ee"); FloatNode floatNode = new FloatNode("2.2"); RelationsAndLogicalOperatorNode testnode1 = new RelationsAndLogicalOperatorNode(stringNode, floatNode, null); RelationsAndLogicalOperatorNode testnode2 = new RelationsAndLogicalOperatorNode(boolNode, boolNode, null); RelationsAndLogicalOperatorNode testnode3 = new RelationsAndLogicalOperatorNode(intNode, intNode, null); - Type testfn1 = typeChecker.relationOperatorTypeCheck(testnode1); - Type testfn2 = typeChecker.relationOperatorTypeCheck(testnode2); - Type testfn3 = typeChecker.relationOperatorTypeCheck(testnode3); + Type testfn1 = SemanticChecker.relationOperatorTypeCheck(testnode1); + Type testfn2 = SemanticChecker.relationOperatorTypeCheck(testnode2); + Type testfn3 = SemanticChecker.relationOperatorTypeCheck(testnode3); assertEquals(Type.UNKNOWN, testfn1, "Should return Type unkown"); assertEquals(Type.BOOLEAN, testfn2, "Should have Type bool"); @@ -165,17 +165,17 @@ void testVisitIfStatement() { blockNodeList.add(new BlockNode()); IfStatementNode node1 = new IfStatementNode(blockNodeList, expressionNodeList); - typeChecker.visitIfStatement(node1); - Type correctType1 = typeChecker.getType(expressionNodeList.get(0)); - Type correctType2 = typeChecker.getType(expressionNodeList.get(1)); + SemanticChecker.visitIfStatement(node1); + Type correctType1 = SemanticChecker.getType(expressionNodeList.get(0)); + Type correctType2 = SemanticChecker.getType(expressionNodeList.get(1)); assertEquals(Type.BOOLEAN, correctType1); assertEquals(Type.BOOLEAN, correctType2); expressionNodeList.add(new ExpressionNode(new IntNode("2"))); blockNodeList.add(new BlockNode()); IfStatementNode node2 = new IfStatementNode(blockNodeList, expressionNodeList); - typeChecker.visitIfStatement(node2); - Type errorType = typeChecker.getType(expressionNodeList.get(2)); + SemanticChecker.visitIfStatement(node2); + Type errorType = SemanticChecker.getType(expressionNodeList.get(2)); assertEquals(Type.INT, errorType, "If statements expression must resolve to bool expression, and this resolve to Type:INT"); } @@ -185,13 +185,13 @@ void testVisitWhileLoop() { ExpressionNode expressionNode1 = new ExpressionNode(new BoolNode("true")); BlockNode blockNode = new BlockNode(); - typeChecker.visitWhileLoop(new WhileLoopNode(expressionNode1, blockNode)); - Type correctType = typeChecker.getType(expressionNode1); + SemanticChecker.visitWhileLoop(new WhileLoopNode(expressionNode1, blockNode)); + Type correctType = SemanticChecker.getType(expressionNode1); assertEquals(Type.BOOLEAN, correctType); ExpressionNode expressionNode2 = new ExpressionNode(new StringNode("hello")); - Type errorType = typeChecker.getType(expressionNode2); - typeChecker.visitWhileLoop(new WhileLoopNode(expressionNode2, blockNode)); + Type errorType = SemanticChecker.getType(expressionNode2); + SemanticChecker.visitWhileLoop(new WhileLoopNode(expressionNode2, blockNode)); assertEquals(Type.STRING, errorType, "While loop expresion must resolve to bool expresion, and this resolve to Type:" + errorType); } @@ -212,7 +212,7 @@ void testTypeCheker1() { Error 3 Identifier:array is alredy used, rename it """; - typeChecker.visitor(astTree); + SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); System.out.println(terminal_Errors + "We get here"); @@ -235,7 +235,7 @@ void testTypeCheker2() { Error 2 Tried to assign the array:array but acces value: 0 is of type:STRING and should be:INT """; - typeChecker.visitor(astTree); + SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); System.out.println(terminal_Errors + "We get here"); @@ -274,7 +274,7 @@ void testTypeCheker9() { Struct Goblin2 already exists """; ; - typeChecker.visitor(astTree); + SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); assertEquals(correct_error.trim(), terminal_Errors); // assertTrue( terminal_Errors.contains(correct_error)); @@ -296,7 +296,7 @@ fn print (y:int)-> int{ You may not redeclare a inbuilt function. The function you tried to redeclare is:print """; ; - typeChecker.visitor(astTree); + SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); assertEquals(correct_error.trim(), terminal_Errors); // assertTrue( terminal_Errors.contains(correct_error)); @@ -321,7 +321,7 @@ void testTypeCheker11() { String correct_error = """ Error 1 Tryied to asssign Type:INT to the variable:test_variable2 that has the type:STRING And that is hella iligal"""; - typeChecker.visitor(astTree); + SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); assertEquals(correct_error.trim(), terminal_Errors); @@ -342,7 +342,7 @@ void testTypeCheker12() { String correct_error = """ Error 1 variable: test_variable already exists in the scope"""; - typeChecker.visitor(astTree); + SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); assertEquals(correct_error.trim(), terminal_Errors); } @@ -363,7 +363,7 @@ void testTypeCheker13() { String correct_error = """ Error 1 could not find the variable y"""; - typeChecker.visitor(astTree); + SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); // assertEquals(correct_error.trim(), terminal_Errors); assertTrue(terminal_Errors.contains(correct_error)); @@ -383,7 +383,7 @@ void testTypeCheker14() { String correct_error = """ Error 1 You have made return statement outside a function THAT IS illigal"""; - typeChecker.visitor(astTree); + SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); assertEquals(correct_error.trim(), terminal_Errors); // assertTrue( terminal_Errors.contains(correct_error)); @@ -406,7 +406,7 @@ fn plus (y:int)-> int{ AstNode astTree = treemaker(code); String correct_error = ""; - typeChecker.visitor(astTree); + SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); assertEquals(correct_error.trim(), terminal_Errors); // assertTrue( terminal_Errors.contains(correct_error)); @@ -433,7 +433,7 @@ fn plus (y:int)-> int{ Error 1 The return type STRING Does not match the return statement of the function int """; - typeChecker.visitor(astTree); + SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); assertEquals(correct_error.trim(), terminal_Errors); // assertTrue( terminal_Errors.contains(correct_error)); diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java index 6bba574..0739341 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java @@ -90,7 +90,7 @@ public void testingIncrementOperator() throws Exception { ParseTree tree = parser.program(); CstToAstVisitor visitor = new CstToAstVisitor(); AstNode astRoot = visitor.visit(tree); - + // System.out.println(astRoot); EvaluatorExecutor interpreter = new EvaluatorExecutor(); interpreter.visit(astRoot); diff --git a/test.carl b/test.carl index fe03cc0..c5509e8 100644 --- a/test.carl +++ b/test.carl @@ -1,28 +1,5 @@ -var x: int = 0 -var y: int = 42 - -fn p() -> void { - x= x + 3 -} -fn q() -> void { - p() -} -fn main() -> int { - x=20 - print(x) - var x : int = 9 - - q() - y = x - return y -} - -print("Før main") -var v : int = main() - -print("efter Main") - -print(y) - -print(v) +var lets : int = 1 +print("It works here") +lets = lets + 1 +print(lets) diff --git a/test5.carl b/test5.carl new file mode 100644 index 0000000..fe03cc0 --- /dev/null +++ b/test5.carl @@ -0,0 +1,28 @@ +var x: int = 0 +var y: int = 42 + +fn p() -> void { + x= x + 3 +} +fn q() -> void { + p() +} +fn main() -> int { + x=20 + print(x) + var x : int = 9 + + q() + y = x + return y +} + +print("Før main") +var v : int = main() + +print("efter Main") + +print(y) + +print(v) + From deedd1b6061b5c13dd3515f6bf18a3c13d3fb7fc Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Tue, 14 May 2024 12:25:44 +0200 Subject: [PATCH 68/94] Please merge i think it workds --- .../java/dk/aau/cs_24_sw_4_16/carl/Main.java | 2 +- test.carl | 31 ++++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index f64e713..98710b6 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -18,7 +18,7 @@ public static void main(String... args) { * Java libary takes in filepath, reads file into memory. Can now be acced * throught identifier fileinput */ - FileInputStream fileInput = new FileInputStream("test.carl"); + FileInputStream fileInput = new FileInputStream("test2.carl"); // CARLLexer is a generated lexer class for the CARL language. // It tokenizes the input stream (breaks the input into meaningful pieces called // tokens). diff --git a/test.carl b/test.carl index c5509e8..fe03cc0 100644 --- a/test.carl +++ b/test.carl @@ -1,5 +1,28 @@ -var lets : int = 1 -print("It works here") -lets = lets + 1 -print(lets) +var x: int = 0 +var y: int = 42 + +fn p() -> void { + x= x + 3 +} +fn q() -> void { + p() +} +fn main() -> int { + x=20 + print(x) + var x : int = 9 + + q() + y = x + return y +} + +print("Før main") +var v : int = main() + +print("efter Main") + +print(y) + +print(v) From 76dda5b060ab3d3f1dc13760c359dffe8214de3d Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Tue, 14 May 2024 12:42:27 +0200 Subject: [PATCH 69/94] Push HAHAHAHAHA --- .../carl/Interpreter/EvaluatorExecutor.java | 7 ++--- .../carl/Interpreter/InbuildClasses.java | 2 +- .../carl/Semantic_A/SemanticChecker.java | 26 +++---------------- 3 files changed, 7 insertions(+), 28 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java index e3266d9..e2de7a9 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java @@ -569,7 +569,7 @@ public AstNode visit(FunctionCallNode node) { } return returnValue; } - scopes.remove(localTable); + } scopes.remove(localTable); activeScope.removeLast(); @@ -640,10 +640,7 @@ public AstNode visit(BinaryOperatorNode node) { } else if (left instanceof FloatNode && right instanceof FloatNode) { return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); } else if (left instanceof FloatNode && right instanceof IntNode) { - AstNode floatnode =BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); - System.out.print("Left node:"+left+" And rigth node:"+ right+" Operator;"+node.getOperator()); - System.out.println("We get in here YES+Result"+floatnode); - + // AstNode floatnode =BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); } else if (left instanceof IntNode && right instanceof FloatNode) { return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java index 8419735..14e0c04 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java @@ -16,7 +16,7 @@ public static void print(FunctionCallNode node, Stack> if (argument instanceof StatementNode) { toPrint.append(((StatementNode) argument).getNode()).append(" "); } else if (argument instanceof IdentifierNode) { - int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; + boolean found = false; for (int i = scopes.size() - 1; i >= 0; i--) { if (scopes.get(i).containsKey(argument.toString())) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java index 927e8da..1617a1e 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java @@ -54,11 +54,7 @@ public void visitProgramNode(ProgramNode node) { } public void visitStatements(StatementNode node) { - if (printDebugger) { - System.out.println("We get in the vist statement"); - System.out.println(node.getClass()); - System.out.println(node.getNode().getClass()); - } + if (node.getNode() instanceof VariableDeclarationNode) { visitVariableDeclaration((VariableDeclarationNode) node.getNode()); } @@ -286,9 +282,9 @@ public void visitMethodCall(MethodCallNode node) { List names = new ArrayList<>(structTypes.keySet()); try { int i = Integer.parseInt(node.getValue().toString()); - System.out.println("Parsed integer value: " + i); + // System.out.println("Parsed integer value: " + i); } catch (NumberFormatException e) { - System.err.println("Error parsing integer: " + e.getMessage()); + // System.err.println("Error parsing integer: " + e.getMessage()); } } @@ -423,9 +419,7 @@ public void visitReturnNode(ReturnStatementNode node) { } public void visitAssignNode(AssignmentNode node) { - if (printDebugger) { - - } + boolean foundIdentifier = false; for (int i = scopes.size() - 1; 0 <= i; i--) { @@ -472,16 +466,8 @@ public void visitAssignNode(AssignmentNode node) { public void visitIfStatement(IfStatementNode node) { Type expression = Type.VOID; - if (printDebugger) { - System.out.println("We get in the If statement"); - } for (int i = 0; i < node.getExpressions().size(); i++) { - - if (printDebugger) { - System.out.println("We get in first for loop"); - System.out.println("Number of expressions:" + node.getExpressions().size()); - } expression = getType(node.getExpressions().get(i).getNode()); if (expression != Type.BOOLEAN) { errorHandler("If statements expression must resolve to bool expression, and this resolve to Type:" @@ -489,10 +475,6 @@ public void visitIfStatement(IfStatementNode node) { } } for (int i = 0; i < node.getBlocks().size(); i++) { - if (printDebugger) { - System.out.println("We get in 2 for loop"); - System.out.println("Number of blocks:" + node.getBlocks().size()); - } HashMap localETable = new HashMap<>(); scopes.add(localETable); visitBlockNode(node.getBlocks().get(i)); From fe753dc9f2d12c2e912b5fdc90637aab739c8817 Mon Sep 17 00:00:00 2001 From: Vincent Kosteyev Bechmann Date: Tue, 14 May 2024 15:22:39 +0200 Subject: [PATCH 70/94] Wrote first part of documentation --- README.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++------- language.md | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 language.md diff --git a/README.md b/README.md index 0420163..eb38796 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,53 @@ CARL: A Roguelike Language ========================== -C.A.R.L. aims to be a general-purpose domain-specific language that -will solve every issue ever encountered in roguelike development, and -maybe fix world hunger while it's at it. The name of this project is -final and may not be debated further. +CARL: A Roguelike Language is a language specialising in writing map +generators for roguelike games. + +Compilation +----------- +**Requirements:** +The program is written in Java 21, and is built with Apache Maven. +Therefore, make sure you have both Maven and JDK >=21 installed before +compiling the program. + +**Compilation:** +To compile, navigate to the root folder (the one containing the +`pom.xml` file), and write: + + mvn package + +Assuming nothing goes wrong during compilation, there should be a +`.jar` file in the `target/` directory. + + +Usage +------- +After you've compiled the interpreter, and written your CARL script, +you can run the interpreter as: + + java -jar carl-1.0.jar script-name.carl + +(make sure to use the correct names for the jar file and script file) + +The interpreter will then run the script, and all output will be sent +to stdout. Output to a file or piping to a program is not natively +supported, but can be done via the shell (e.g. bash or cmd). + + +Script language +--------------- +A description of how to write in the language can be found in +[language.md](language.md) + +Contact +------- This is a 4th semester project for the Software course at Aalborg -University. We can be contacted via e-mail as -cs-24-sw-4-16@student.aau.dk, if you have any questions for some -reason or another. +University. Chances are that we will never look back at this project +ever again after June 25, 2024 (our project exam date), except in +shame. + +However, if by some chance you've been trapped by a sphinx and part of +its riddle involves knowledge this software, we can be contacted via +email as cs-24-sw-4-16@student.aau.dk. diff --git a/language.md b/language.md new file mode 100644 index 0000000..d399dc5 --- /dev/null +++ b/language.md @@ -0,0 +1,41 @@ +# Programming in the CARL scripting language + +In general, CARL is a simple imperative language. Statements are +separated by newlines (no semicolons), and are executed one after the +other. + +## Variables + +### Declaration + +New variables are defined using the syntax: + + var : = + +They can be edited without the `var` keyword or specifying type: + + = + +As an example, this code: + + var foo: int = 3 + print(foo) + foo = foo + 1 + print(foo) + +would output: + + 3 + 4 + +### Types + +CARL has the following primitive types: + +| Type | Explanation | Examples | +|-----------|------------------------------------------------------------------------------------------------------------|--------------------------------------| +| `bool` | Boolean value: either `true` or `false`. | `true`, `false` | +| `int` | Integer value: Can be any whole number, either positive or negative (currently limited to 32-bit integers) | `1`, `2`, `32194`, `-900000` | +| `float` | Floating-point value: Can be any real number, with 64-bit precision. | `1.0`, `0.0`, `-10000.0`, `1.404001` | +| `string` | Any text, represented as a string of characters. | "Hello, World!", "123" | + From 3d236807304f1de47dd610b74b34836bc7d448b9 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Wed, 15 May 2024 08:52:45 +0200 Subject: [PATCH 71/94] Bug fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Type checker bug fixes - [x] Program array må gerne være af type string, argumenter skal altid være af type int - [x] array map skal initiliseres i array deklaration. som en stable ting - [x] Array Assignment gik tidligere ikke ingennem alle scopes for at prøve at finde variable. Fixet nu - [x] Vi håndtere ikke cassen med method call, hvilket smider fejl når den bruges, fordi den(Gettype) ikke kan resolve typen. var roomSize : int = room.size() - [x] Relational operations kunne ikke håndere sammenligning mellem 2 strings. kan nu --- .gitignore | 1 + .../java/dk/aau/cs_24_sw_4_16/carl/Main.java | 2 +- .../carl/Semantic_A/SemanticChecker.java | 96 +++++++++---------- 3 files changed, 48 insertions(+), 51 deletions(-) diff --git a/.gitignore b/.gitignore index b74500d..7513c21 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ target/ .classpath .project .factorypath +map.json diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index 98710b6..8a01729 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -43,7 +43,7 @@ public static void main(String... args) { // The visit method walks the parse tree and constructs the AST AstNode astRoot = visitor.visit(tree); //System.out.println(astRoot); - + SemanticChecker typeChecker = new SemanticChecker(); typeChecker.visitor(astRoot); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java index 1617a1e..f7275d3 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java @@ -41,7 +41,7 @@ public SemanticChecker() { } public void visitor(AstNode node) { - /// System.out.println(node); + if (node instanceof ProgramNode) { visitProgramNode((ProgramNode) node); } @@ -54,7 +54,7 @@ public void visitProgramNode(ProgramNode node) { } public void visitStatements(StatementNode node) { - + if (node.getNode() instanceof VariableDeclarationNode) { visitVariableDeclaration((VariableDeclarationNode) node.getNode()); } @@ -90,16 +90,19 @@ public void visitStatements(StatementNode node) { visitPropertyAssignment((PropertyAssignmentNode) node.getNode()); } if (node.getNode() instanceof MethodCallNode) { - errorHandler("ewjrngkewgjewkejnweklrglewrkngewkrgkwen"); - visitMethodCall((MethodCallNode) node.getNode()); + // errorHandler("ewjrngkewgjewkejnweklrglewrkngewkrgkwen"); + //visitMethodCall((MethodCallNode) node.getNode()); } } public void errorHandler(String errorMessage) { thereWasAnError = true; - System.err.println("Error " + errorNumber); - errorNumber = errorNumber + 1; - System.err.println(errorMessage); + + System.err.println("Error " + errorNumber); + errorNumber = errorNumber + 1; + System.err.println(errorMessage); + + } /* @@ -146,17 +149,18 @@ public void visistArrayAccesNodeFn(ArrayAccessNode node) { public void visistArrayAssignment(ArrayAssignmentNode node) { String identifier = node.getIdentifier().toString(); Boolean found = false; - + Type arrayType = Type.UNKNOWN; found = scopes.getLast().containsKey(identifier); - // System.out.println(activeScope); - for (int i = activeScope.getLast(); i < scopes.size(); i++) { + + for (int i = scopes.size() - 1; 0 <= i; i--) { + if (scopes.get(i).containsKey(identifier)) { found = true; + arrayType = scopes.get(i).get(identifier); } } if (found) { - Type arrayType = scopes.getLast().get(identifier); Boolean validTypesaccesTypes = true; Type sizeType = Type.UNKNOWN; @@ -216,7 +220,7 @@ public void visistarrayDekleration(ArrayDefinitionNode node) { for (int i = 0; i < sizes.size(); i++) { AstNode astNode = sizes.get(i); sizeType = getType(astNode); - if (sizeType != arrayType) { + if (sizeType != Type.INT) { arguementNumber = i; validTypes = false; @@ -246,18 +250,10 @@ public void visitPropertyAssignment(PropertyAssignmentNode node) { } } - // Ved ikke om den virker endnu, kan være det er forkert + public Type visitPropertyAccessNode(PropertyAccessNode node) { List validPropertyAccess = new ArrayList<>(Arrays.asList("size", "get")); - // Viker ikke til det her behøves at tjekkes - // Type structType = getType(node.getList()); - // System.out.println(structType); - // - // if (!structTypes.containsValue(structType)) { - // errorHandler("could not find the struct type: " + structType); - // return Type.UNKNOWN; - // } - + String firstIdentifier = node.getIdentifiers().get(0).toString(); if (!structVariablesTable.containsKey(firstIdentifier) && !validPropertyAccess.contains(firstIdentifier)) { errorHandler("could not find the struct variable: " + firstIdentifier); @@ -278,15 +274,7 @@ public Type visitPropertyAccessNode(PropertyAccessNode node) { return Type.UNKNOWN; } - public void visitMethodCall(MethodCallNode node) { - List names = new ArrayList<>(structTypes.keySet()); - try { - int i = Integer.parseInt(node.getValue().toString()); - // System.out.println("Parsed integer value: " + i); - } catch (NumberFormatException e) { - // System.err.println("Error parsing integer: " + e.getMessage()); - } - } + public Type relationOperatorTypeCheck(RelationsAndLogicalOperatorNode node) { @@ -306,6 +294,10 @@ public Type relationOperatorTypeCheck(RelationsAndLogicalOperatorNode node) { } else if (leftType == Type.BOOLEAN && rightType == Type.BOOLEAN) { return Type.BOOLEAN; } + else if (leftType == Type.STRING && rightType == Type.STRING) { + return Type.BOOLEAN; + } + errorHandler("Wrong types for relation operation:" + leftType + ":" + left + " And:" + right + ":" + rightType); @@ -381,12 +373,11 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { public Type getVariable(IdentifierNode node) { if (scopes.getLast().containsKey(node.getIdentifier().toString())) { - // System.out.println("234324234"+scopes.getFirst()); + currentIdentifierCheck = node.getIdentifier().toString(); return scopes.getLast().get(node.getIdentifier().toString()); } - // System.out.println("We get in here:"+node.getIdentifier().toString()); - // System.out.println("The scopes:"+scopes); + for (int i = activeScope.getLast(); i < scopes.size(); i++) { if (scopes.get(i).containsKey(node.getIdentifier().toString())) { currentIdentifierCheck = node.getIdentifier().toString(); @@ -402,7 +393,7 @@ public Type getVariable(IdentifierNode node) { // Check if return = type er det samme som den function den står i. public void visitReturnNode(ReturnStatementNode node) { Type returnType = getType(node.getReturnValue()); - // System.out.println(returnType); + if (currentActiveFunction == "") { errorHandler("You have made return statement outside a function THAT IS illigal"); } else { @@ -419,18 +410,14 @@ public void visitReturnNode(ReturnStatementNode node) { } public void visitAssignNode(AssignmentNode node) { - + boolean foundIdentifier = false; for (int i = scopes.size() - 1; 0 <= i; i--) { - // System.out.println("This many scopes:" + i + ":" + scopes.get(i)); + HashMap ETable = scopes.get(i); - // System.out.println("Scopes:"+scopes+"CurrentScopeWecheck:"); - // System.out.println("Here it break2s"+ETable); - if (true) { - // System.out.println("Identifier" + node.getIdentifier().toString()); - // System.out.println("Etable:" + ETable); - } + + if (ETable.containsKey(node.getIdentifier().toString())) {// hvis x er i scope foundIdentifier = true; // tjekke om det er lovligt. @@ -492,12 +479,12 @@ public void visitWhileLoop(WhileLoopNode node) { HashMap localTable = new HashMap<>(); scopes.add(localTable); visitBlockNode(node.getBlock()); - System.out.println(localTable); + scopes.remove(localTable); } public void visitFunctionDefinition(FunctionDefinitionNode node) { - // System.out.println(node + "We get in here"); + if (!listOfInbuiltFunctions.contains(node.getIdentifier().toString())) { if (!typeOfReturnFunction.containsKey(node.toString()) && !functionParameters.containsKey(node.toString())) { @@ -528,8 +515,7 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { visitBlockNode(node.getBlock());// Alle statement i fn. En af dem er returnStatement currentActiveFunction = ""; if (!hasReturnStatement && Type.VOID != getType(node.getReturnType())) { - // System.out.println(getType(node.getReturnType())); - // System.out.println(typeOfReturnFunction); + errorHandler("Missing return statement in function declartion:" + node.getIdentifier().toString()); } hasReturnStatement = false; @@ -550,7 +536,7 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { * Vi skal sige hvis arguemtnet er en forkert type. */ public void visitFunctionCall(FunctionCallNode node) { - // System.out.println("we get in here how?" + node); + if (!listOfInbuiltFunctions.contains(node.getFunctionName().toString())) { HashMap localETable = new HashMap<>(); @@ -654,6 +640,12 @@ public void visitBlockNode(BlockNode node) { } } + public Type resolveMethodCallType(MethodCallNode node) { + Type returnType = Type.INT; + + return returnType; + } + public Type getType(Object node) { Type type = Type.UNKNOWN; @@ -671,7 +663,10 @@ public Type getType(Object node) { } else if (node instanceof PropertyAccessNode) { type = visitPropertyAccessNode((PropertyAccessNode) node); } else if (node instanceof MethodCallNode) { - visitMethodCall((MethodCallNode) node); + MethodCallNode methodCallNode = (MethodCallNode) node; + type = resolveMethodCallType(methodCallNode); + + } else if (node instanceof BinaryOperatorNode) { type = binaryOperatorTypeCheck((BinaryOperatorNode) node); } else if (node instanceof RelationsAndLogicalOperatorNode) { @@ -738,7 +733,8 @@ public Type getType(Object node) { default: break; } - } else { + } + else { errorHandler("The node we get failed to handle:" + node.getClass()); } return type; From 729af59d50e17e6f5d2ebb765e920bdcb04eeb12 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Wed, 15 May 2024 09:08:17 +0200 Subject: [PATCH 72/94] =?UTF-8?q?Jeg=20har=20=C3=A6ndre=20scopet=20rundt?= =?UTF-8?q?=20om=20kring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Har fundet kode som aldrig gør noget. har fjernet udkommenteret kode. Da det ikke var pænt --- .../carl/Interpreter/EvaluatorExecutor.java | 79 +++++++------------ 1 file changed, 30 insertions(+), 49 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java index e2de7a9..c9b34a3 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java @@ -59,7 +59,8 @@ public AstNode roomCall(MethodCallNode node) { throw new RuntimeException("out of bounds"); } } else if (((ArgumentListNode) node.getValue()).getList().get(0) instanceof IdentifierNode) { - IntNode in = ((IntNode) getVariable((IdentifierNode) ((ArgumentListNode) node.getValue()).getList().get(0))); + IntNode in = ((IntNode) getVariable( + (IdentifierNode) ((ArgumentListNode) node.getValue()).getList().get(0))); int index = in.getValue(); if (index < rooms.size()) { return rooms.get(in.getValue()).get(node.getIdentifierNode().toString()); @@ -104,7 +105,7 @@ public AstNode visit(MethodCallNode node) { } public AstNode visit(StatementNode node) { - // System.out.println(scopes); + if (node.getNode() instanceof AssignmentNode) { visit((AssignmentNode) node.getNode()); } else if (node.getNode() instanceof VariableDeclarationNode) { @@ -141,7 +142,8 @@ public void visit(StructureDefinitionNode node) { HashMap object = new HashMap<>(); for (var variable : node.getVariableDeclarations()) { if (variable.getValue() instanceof IdentifierNode) { - object.put(variable.getIdentifier().toString(), getVariable((new IdentifierNode(variable.getValue().toString())))); + object.put(variable.getIdentifier().toString(), + getVariable((new IdentifierNode(variable.getValue().toString())))); } else { object.put(variable.getIdentifier().toString(), variable.getValue()); @@ -247,17 +249,19 @@ public void visit(IfStatementNode node) { } public AstNode getVariable(IdentifierNode node) { - // for (HashMap vTable : scopes) { - int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; - for (int i = scopes.size() - 1; i >= towards; i--) { + // Ændring så den kikker igennem alle scopes, fra det mest nestede scope mod det + // øverste scope + for (int i = scopes.size() - 1; i >= 0; i--) { if (scopes.get(i).containsKey(node.getIdentifier())) { return scopes.get(i).get(node.getIdentifier()); } } + + // Det her kode gør ikke noget, bliver aldrig reached? int from = 0; if (!activeScope.isEmpty()) { - from = activeScope.getFirst()-1; + from = activeScope.getFirst() - 1; } else { from = scopes.size() - 1; } @@ -266,30 +270,25 @@ public AstNode getVariable(IdentifierNode node) { return scopes.get(i).get(node.getIdentifier()); } } - // if (scopes.getFirst().containsKey(node.getIdentifier())) { - // return scopes.getFirst().get(node.getIdentifier()); - // } + // Har tjekket at Mantas test2 program virker, uden, det gør det. throw new RuntimeException("could not find the variable " + node.getIdentifier()); } public void visit(AssignmentNode node) { - - //System.out.println("fycj me"+node); - int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; - // System.out.println(towards+":"+activeScope.getLast()); + // Ændring så den kikker igennem alle scopes, fra det mest nestede scope mod det + // øverste scope for (int i = scopes.size() - 1; i >= 0; i--) { - // System.out.println(scopes.get(i)+i); if (scopes.get(i).containsKey(node.getIdentifier().getIdentifier())) { - // if (vTable.containsKey(node.getIdentifier().toString())) { AstNode nodeToChange = scopes.get(i).get(node.getIdentifier().toString()); AstNode toChange = node.getValue(); replaceValue(nodeToChange, toChange); return; } } + // Det her kode gør ikke noget:1 int from = 0; if (!activeScope.isEmpty()) { - from = activeScope.getFirst() -1 ; + from = activeScope.getFirst() - 1; } else { from = scopes.size() - 1; } @@ -302,13 +301,8 @@ public void visit(AssignmentNode node) { return; } } - // if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { - // AstNode nodeToChange = - // scopes.getFirst().get(node.getIdentifier().toString()); - // AstNode toChange = node.getValue(); - // replaceValue(nodeToChange, toChange); - // return; - // } + // Det her kode gør ikke noget:1 har prøvet at slette det og det gør ikke nogen + // forskel? throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); } @@ -316,8 +310,6 @@ public void visit(AssignmentNode node) { public void visit(VariableDeclarationNode node) { if (!scopes.getLast().containsKey(node.getIdentifier().getIdentifier())) { - // if (!idExists(node.getIdentifier().toString())) { - AstNode toChange = node.getValue(); if (toChange instanceof FunctionCallNode) { toChange = visit((FunctionCallNode) toChange); @@ -336,14 +328,14 @@ public void visit(VariableDeclarationNode node) { } else if (variable instanceof StringNode) { scopes.getLast().put(node.getIdentifier().toString(), new StringNode(variable.toString())); } else if (variable instanceof BoolNode) { - scopes.getLast().put(node.getIdentifier().toString(), new BoolNode(((BoolNode) variable).getValue())); + scopes.getLast().put(node.getIdentifier().toString(), + new BoolNode(((BoolNode) variable).getValue())); } else { throw new RuntimeException("haa"); } } } - } else if (toChange instanceof PropertyAccessNode) { toChange = visit((PropertyAccessNode) toChange); scopes.getLast().put(node.getIdentifier().toString(), toChange); @@ -457,15 +449,16 @@ public void visit(ArrayDefinitionNode node) { private boolean idExists(String id) { boolean found = false; - int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; - for (int i = scopes.size() - 1; i >= towards; i--) { + // ændring til at loope igennem alting + for (int i = scopes.size() - 1; i >= 0; i--) { if (scopes.get(i).containsKey(id)) { found = true; } } + // Bruges ikke til noget igen :2 int from = 0; if (!activeScope.isEmpty()) { - from = activeScope.getFirst() -1; + from = activeScope.getFirst() - 1; } else { from = scopes.size() - 1; } @@ -474,20 +467,7 @@ private boolean idExists(String id) { found = true; } } - // if (scopes.getFirst().containsKey(id)) { - // found = true; - // } - - // if (scopes.getFirst().containsKey(id)) { - // found = true; - // } - // - // for (int i = activeScope.getLast(); i < scopes.size(); i++) { - // if (scopes.get(i).containsKey(id)) { - // found = true; - // } - // } - + // Bruges ikke til noget igen :2 return found; } @@ -539,7 +519,7 @@ public AstNode visit(FunctionCallNode node) { } else if (node.getFunctionName().toString().equals("setSeed")) { InbuildClasses.setSeed(node); } else { - // Boolean returnVoidCase = false; + // Boolean returnVoidCase = false; HashMap localTable = new HashMap<>(); scopes.add(localTable); activeScope.add(scopes.size() - 1); @@ -569,7 +549,7 @@ public AstNode visit(FunctionCallNode node) { } return returnValue; } - + } scopes.remove(localTable); activeScope.removeLast(); @@ -640,7 +620,7 @@ public AstNode visit(BinaryOperatorNode node) { } else if (left instanceof FloatNode && right instanceof FloatNode) { return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); } else if (left instanceof FloatNode && right instanceof IntNode) { - // AstNode floatnode =BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); + return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); } else if (left instanceof IntNode && right instanceof FloatNode) { return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); @@ -679,7 +659,8 @@ public AstNode visit(RelationsAndLogicalOperatorNode node) { return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); } - throw new RuntimeException("RelationsAndLogicalOperator not implemented clause " + left.getClass() + " " + right.getClass()); + throw new RuntimeException( + "RelationsAndLogicalOperator not implemented clause " + left.getClass() + " " + right.getClass()); } public AstNode visit(WhileLoopNode node) { From 81b25290b7595f1799ac7d8245dc4b2e9cfc74d1 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Wed, 15 May 2024 09:11:53 +0200 Subject: [PATCH 73/94] Sidste kommit --- .../dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java index 14e0c04..dc0ccb7 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java @@ -25,7 +25,7 @@ public static void print(FunctionCallNode node, Stack> break; } } - + // Kode bliver aldrig kørt? if (!found) { int from = 0; if (!activeScope.isEmpty()) { @@ -40,6 +40,7 @@ public static void print(FunctionCallNode node, Stack> } } + // Slet possible? } else if (argument instanceof FloatNode) { System.out.println("We get in Floatnode"); From 53ca38cd279a9b0fe150a51109023b4541785661 Mon Sep 17 00:00:00 2001 From: MShadiF Date: Thu, 16 May 2024 12:40:23 +0200 Subject: [PATCH 74/94] Inbuilt function for spawning monster --- .../carl/Interpreter/InbuildClasses.java | 29 ++++++++++++++++--- .../carl/Semantic_A/SemanticChecker.java | 2 +- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java index 14e0c04..7f5fdff 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java @@ -159,6 +159,29 @@ public static void generateCorridors(FunctionCallNode node, Stack> scopes, HashMap> tileInformationEnemy, List> rooms) { ArrayNode map = ((ArrayNode) scopes.getFirst().get("map")); + System.out.println(tileInformationEnemy); + if (!node.getArguments().isEmpty()) { + if(node.getArguments().size() == 1 && node.getArguments().get(0) instanceof IntNode) { + int difficulty = ((IntNode) node.getArguments().get(0)).getValue(); + while (difficulty > 0) { + int roomSpawn = EvaluatorExecutor.rand.nextInt(0,rooms.size() - 2); + int x = EvaluatorExecutor.rand.nextInt(((IntNode) rooms.get(roomSpawn).get("x")).getValue(), (((IntNode) rooms.get(roomSpawn).get("x")).getValue() + ((IntNode) rooms.get(roomSpawn).get("width")).getValue())); + int y = EvaluatorExecutor.rand.nextInt(((IntNode) rooms.get(roomSpawn).get("y")).getValue(), (((IntNode) rooms.get(roomSpawn).get("y")).getValue() + ((IntNode) rooms.get(roomSpawn).get("height")).getValue())); + var key = tileInformationEnemy.keySet().toArray()[EvaluatorExecutor.rand.nextInt(0,tileInformationEnemy.size())]; + StringNode symbol = ((StringNode) tileInformationEnemy.get(key).get("symbol")); + int difficultyMonster = ((IntNode) tileInformationEnemy.get(key).get("difficulty")).getValue(); + System.out.println(difficultyMonster); + if (difficulty >= difficultyMonster) { + if (((StringNode) map.get(y,x)).getValue().equals("f")) { + System.out.println("Hello"); + map.set(new StringNode(symbol.getValue()), y, x); + difficulty -= difficultyMonster; + } + } + } + } + } + int yPlayer = EvaluatorExecutor.rand.nextInt(((IntNode) rooms.get(rooms.size() - 1).get("x")).getValue(), (((IntNode) rooms.get(rooms.size() - 1).get("x")).getValue() + ((IntNode) rooms.get(rooms.size() - 1).get("width")).getValue())); int xPlayer = EvaluatorExecutor.rand.nextInt(((IntNode) rooms.get(rooms.size() - 1).get("y")).getValue(), (((IntNode) rooms.get(rooms.size() - 1).get("y")).getValue() + ((IntNode) rooms.get(rooms.size() - 1).get("height")).getValue())); map.set(new StringNode("p"), xPlayer, yPlayer); @@ -245,12 +268,11 @@ private static String generatePrint(Stack> scopes, Hash } private static void tileInformationStringBuilder(HashMap> tileInformation, StringBuilder sb) { - for (String name : tileInformation.keySet()) { for (HashMap innerHashMap : tileInformation.values()) { sb.append(""" {"symbol" : - """).append(((StringNode) innerHashMap.get("symbol")).getValue()).append(""" - ,"info":{ + """).append("\"").append(((StringNode) innerHashMap.get("symbol")).getValue()).append(""" + ","info":{ """); for (String key : innerHashMap.keySet()) { if (!key.equals("symbol")) { @@ -272,7 +294,6 @@ private static void tileInformationStringBuilder(HashMap typeOfReturnFunction; HashMap> functionParameters; - List listOfInbuiltFunctions = new ArrayList<>(Arrays.asList("print", "generateGrid", "generateRooms", + List listOfInbuiltFunctions = new ArrayList<>(Arrays.asList("print", "generateMap", "generateRooms", "generateCorridors", "generateSpawns", "printMap", "generatePrint", "writeToFile", "overlap", "tileInformationStringBuilder", "setSeed")); HashMap> structVariablesTable; From 3165a0feb740e620dd4e18b4545cd46242c4639d Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Thu, 16 May 2024 13:08:22 +0200 Subject: [PATCH 75/94] not done --- .../carl/Interpreter/EvaluatorExecutor.java | 91 ++++++-- .../carl/Semantic_A/SemanticChecker.java | 203 +++++++++++++----- test.carl | 38 ++-- 3 files changed, 229 insertions(+), 103 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java index e2de7a9..6ac0c42 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java @@ -1,7 +1,7 @@ package dk.aau.cs_24_sw_4_16.carl.Interpreter; import dk.aau.cs_24_sw_4_16.carl.CstToAst.*; - +import dk.aau.cs_24_sw_4_16.carl.Semantic_A.Type; import java.io.IOException; import java.util.*; import java.util.stream.IntStream; @@ -15,6 +15,7 @@ public class EvaluatorExecutor { HashMap> tileInformationFloor; HashMap> tileInformationWall; List> rooms; + Type wantedType = Type.UNKNOWN; // This will be the same instance for all instances of Interpreter // This might have unexpected consequences if we expand the program to use // more than one instance of Interpreter at a time, but it doesn't yet, so @@ -59,7 +60,8 @@ public AstNode roomCall(MethodCallNode node) { throw new RuntimeException("out of bounds"); } } else if (((ArgumentListNode) node.getValue()).getList().get(0) instanceof IdentifierNode) { - IntNode in = ((IntNode) getVariable((IdentifierNode) ((ArgumentListNode) node.getValue()).getList().get(0))); + IntNode in = ((IntNode) getVariable( + (IdentifierNode) ((ArgumentListNode) node.getValue()).getList().get(0))); int index = in.getValue(); if (index < rooms.size()) { return rooms.get(in.getValue()).get(node.getIdentifierNode().toString()); @@ -104,7 +106,7 @@ public AstNode visit(MethodCallNode node) { } public AstNode visit(StatementNode node) { - // System.out.println(scopes); + // System.out.println(scopes); if (node.getNode() instanceof AssignmentNode) { visit((AssignmentNode) node.getNode()); } else if (node.getNode() instanceof VariableDeclarationNode) { @@ -141,7 +143,8 @@ public void visit(StructureDefinitionNode node) { HashMap object = new HashMap<>(); for (var variable : node.getVariableDeclarations()) { if (variable.getValue() instanceof IdentifierNode) { - object.put(variable.getIdentifier().toString(), getVariable((new IdentifierNode(variable.getValue().toString())))); + object.put(variable.getIdentifier().toString(), + getVariable((new IdentifierNode(variable.getValue().toString())))); } else { object.put(variable.getIdentifier().toString(), variable.getValue()); @@ -257,7 +260,7 @@ public AstNode getVariable(IdentifierNode node) { } int from = 0; if (!activeScope.isEmpty()) { - from = activeScope.getFirst()-1; + from = activeScope.getFirst() - 1; } else { from = scopes.size() - 1; } @@ -273,12 +276,12 @@ public AstNode getVariable(IdentifierNode node) { } public void visit(AssignmentNode node) { - - //System.out.println("fycj me"+node); + + // System.out.println("fycj me"+node); int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; - // System.out.println(towards+":"+activeScope.getLast()); + // System.out.println(towards+":"+activeScope.getLast()); for (int i = scopes.size() - 1; i >= 0; i--) { - // System.out.println(scopes.get(i)+i); + // System.out.println(scopes.get(i)+i); if (scopes.get(i).containsKey(node.getIdentifier().getIdentifier())) { // if (vTable.containsKey(node.getIdentifier().toString())) { AstNode nodeToChange = scopes.get(i).get(node.getIdentifier().toString()); @@ -289,7 +292,7 @@ public void visit(AssignmentNode node) { } int from = 0; if (!activeScope.isEmpty()) { - from = activeScope.getFirst() -1 ; + from = activeScope.getFirst() - 1; } else { from = scopes.size() - 1; } @@ -313,12 +316,53 @@ public void visit(AssignmentNode node) { throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); } + + public void visit(VariableDeclarationNode node) { if (!scopes.getLast().containsKey(node.getIdentifier().getIdentifier())) { - // if (!idExists(node.getIdentifier().toString())) { - + AstNode toChange = node.getValue(); + String type = node.getType().getType(); + if (toChange instanceof MethodCallNode) { + + + if (type.equals("int")) { + wantedType = Type.INT; + } else if (type.equals("string")) { + wantedType = Type.STRING; + } else if (type.equals("bool")) { + wantedType = Type.BOOLEAN; + } else if (type.equals("float")) { + wantedType = Type.FLOAT; + } + + System.out.println("Wanted type in methodCall node:" + wantedType); + toChange = visit((MethodCallNode) toChange); + System.out.println(toChange.getClass()); + Type tochange_Type = Type.UNKNOWN; + if (toChange instanceof IntNode) { + tochange_Type = Type.INT; + } else if (toChange instanceof FloatNode) { + tochange_Type = Type.FLOAT; + } else if (toChange instanceof StringNode) { + tochange_Type = Type.STRING; + } else if (toChange instanceof BoolNode) { + tochange_Type = Type.BOOLEAN; + + } + + if (wantedType.equals(tochange_Type)) { + + scopes.getLast().put(node.getIdentifier().toString(), toChange); + } else { + System.err.println("You tried to assign Type:" + tochange_Type + " To the variable:" + + node.getIdentifier().getIdentifier() + " of type:" + wantedType + + " in runtime and that is illagal"); + } + + } + if (toChange instanceof FunctionCallNode) { toChange = visit((FunctionCallNode) toChange); } @@ -336,14 +380,14 @@ public void visit(VariableDeclarationNode node) { } else if (variable instanceof StringNode) { scopes.getLast().put(node.getIdentifier().toString(), new StringNode(variable.toString())); } else if (variable instanceof BoolNode) { - scopes.getLast().put(node.getIdentifier().toString(), new BoolNode(((BoolNode) variable).getValue())); + scopes.getLast().put(node.getIdentifier().toString(), + new BoolNode(((BoolNode) variable).getValue())); } else { throw new RuntimeException("haa"); } } } - } else if (toChange instanceof PropertyAccessNode) { toChange = visit((PropertyAccessNode) toChange); scopes.getLast().put(node.getIdentifier().toString(), toChange); @@ -351,10 +395,7 @@ public void visit(VariableDeclarationNode node) { } else if (toChange instanceof ArrayAccessNode) { toChange = visit((ArrayAccessNode) node.getValue()); scopes.getLast().put(node.getIdentifier().toString(), toChange); - } else if (toChange instanceof MethodCallNode) { - toChange = visit((MethodCallNode) toChange); - scopes.getLast().put(node.getIdentifier().toString(), toChange); - } else if (toChange instanceof IntNode) { + } else if (toChange instanceof IntNode) { scopes.getLast().put(node.getIdentifier().toString(), new IntNode(toChange.toString())); } else if (toChange instanceof FloatNode) { scopes.getLast().put(node.getIdentifier().toString(), new FloatNode(toChange.toString())); @@ -364,8 +405,10 @@ public void visit(VariableDeclarationNode node) { scopes.getLast().put(node.getIdentifier().toString(), new BoolNode(((BoolNode) toChange).getValue())); } } else { + wantedType = Type.UNKNOWN; throw new RuntimeException("variable " + node.getIdentifier() + " already exists in the current scope"); } + wantedType = Type.UNKNOWN; } private int[] astNodeListToIntArray(List ints) { @@ -465,7 +508,7 @@ private boolean idExists(String id) { } int from = 0; if (!activeScope.isEmpty()) { - from = activeScope.getFirst() -1; + from = activeScope.getFirst() - 1; } else { from = scopes.size() - 1; } @@ -539,7 +582,7 @@ public AstNode visit(FunctionCallNode node) { } else if (node.getFunctionName().toString().equals("setSeed")) { InbuildClasses.setSeed(node); } else { - // Boolean returnVoidCase = false; + // Boolean returnVoidCase = false; HashMap localTable = new HashMap<>(); scopes.add(localTable); activeScope.add(scopes.size() - 1); @@ -569,7 +612,7 @@ public AstNode visit(FunctionCallNode node) { } return returnValue; } - + } scopes.remove(localTable); activeScope.removeLast(); @@ -640,7 +683,8 @@ public AstNode visit(BinaryOperatorNode node) { } else if (left instanceof FloatNode && right instanceof FloatNode) { return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); } else if (left instanceof FloatNode && right instanceof IntNode) { - // AstNode floatnode =BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); + // AstNode floatnode =BinaryOperatorNode.getAstNodeValue(left, right, + // node.getOperator()); return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); } else if (left instanceof IntNode && right instanceof FloatNode) { return BinaryOperatorNode.getAstNodeValue(left, right, node.getOperator()); @@ -679,7 +723,8 @@ public AstNode visit(RelationsAndLogicalOperatorNode node) { return RelationsAndLogicalOperatorNode.getAstNodeValue(left, right, node.getOperator()); } - throw new RuntimeException("RelationsAndLogicalOperator not implemented clause " + left.getClass() + " " + right.getClass()); + throw new RuntimeException( + "RelationsAndLogicalOperator not implemented clause " + left.getClass() + " " + right.getClass()); } public AstNode visit(WhileLoopNode node) { diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java index 1617a1e..737dce1 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java @@ -13,8 +13,7 @@ public class SemanticChecker { List listOfInbuiltFunctions = new ArrayList<>(Arrays.asList("print", "generateGrid", "generateRooms", "generateCorridors", "generateSpawns", "printMap", "generatePrint", "writeToFile", "overlap", "tileInformationStringBuilder", "setSeed")); - HashMap> structVariablesTable; - HashMap structTypes; + HashMap eTable;// variable table, identifier(x) og node(int) Stack> scopes; // scope table, variable identifier(x) og node Deque activeScope;// Hvilket scope vi er i nu @@ -25,6 +24,14 @@ public class SemanticChecker { public Boolean thereWasAnError = false; String currentIdentifierCheck = ""; Boolean struct_variable_declarion_failed = false; + // KUN TIL STRUCTS + HashMap structTypes; + HashMap> tileInformationEnemy; + HashMap> tileInformationFloor; + HashMap> tileInformationWall; + List> rooms; + HashMap> structVariablesTable; + Type wanted_type =Type.UNKNOWN; public SemanticChecker() { @@ -38,10 +45,14 @@ public SemanticChecker() { functionParameters = new HashMap<>(); structVariablesTable = new HashMap<>(); structTypes = new HashMap<>(); + tileInformationEnemy = new HashMap<>(); + tileInformationFloor = new HashMap<>(); + tileInformationWall = new HashMap<>(); + rooms = new ArrayList<>(); } public void visitor(AstNode node) { - /// System.out.println(node); + /// System.out.println(node); if (node instanceof ProgramNode) { visitProgramNode((ProgramNode) node); } @@ -54,7 +65,7 @@ public void visitProgramNode(ProgramNode node) { } public void visitStatements(StatementNode node) { - + if (node.getNode() instanceof VariableDeclarationNode) { visitVariableDeclaration((VariableDeclarationNode) node.getNode()); } @@ -249,14 +260,6 @@ public void visitPropertyAssignment(PropertyAssignmentNode node) { // Ved ikke om den virker endnu, kan være det er forkert public Type visitPropertyAccessNode(PropertyAccessNode node) { List validPropertyAccess = new ArrayList<>(Arrays.asList("size", "get")); - // Viker ikke til det her behøves at tjekkes - // Type structType = getType(node.getList()); - // System.out.println(structType); - // - // if (!structTypes.containsValue(structType)) { - // errorHandler("could not find the struct type: " + structType); - // return Type.UNKNOWN; - // } String firstIdentifier = node.getIdentifiers().get(0).toString(); if (!structVariablesTable.containsKey(firstIdentifier) && !validPropertyAccess.contains(firstIdentifier)) { @@ -278,14 +281,39 @@ public Type visitPropertyAccessNode(PropertyAccessNode node) { return Type.UNKNOWN; } - public void visitMethodCall(MethodCallNode node) { - List names = new ArrayList<>(structTypes.keySet()); - try { - int i = Integer.parseInt(node.getValue().toString()); - // System.out.println("Parsed integer value: " + i); - } catch (NumberFormatException e) { - // System.err.println("Error parsing integer: " + e.getMessage()); - } + public Type visitMethodCall(MethodCallNode node) { // + // Her skal vi først finde ud af vilken type struct vi skal lede i + // Så skal vi finde ud af om structet eksistere + // Så skal vi indexe og tjekke dens typer imod den type ting itng + + /* String identifier = node.getIdentifierNode().toString(); + System.out.println("Identifier:"+identifier); // Variable vi leder efter i struct + + PropertyAccessNode propertyAccessNode = node.getPropertyAccessContext(); + System.out.println("Propertyascc:"+propertyAccessNode); + + String list = propertyAccessNode.getList(); + List identifiernodes = propertyAccessNode.getIdentifiers(); + System.out.println("Liste:"+list);// Type af struct hasmap vi skal kikke i + System.out.println("Identifiernodes"+identifiernodes); + + for (int i = identifiernodes.size()-1; i>=0;i--){ + System.out.println("Identifiernode:"+i+":"+identifiernodes.get(i)); + } + + if (node.getValue() instanceof ArgumentListNode) { + // Cast node to ArgumentListNode + ArgumentListNode argumentListNode = (ArgumentListNode) node.getValue(); + // You can now use argumentListNode for further operations + System.out.println(argumentListNode); + List liste = argumentListNode.getList(); + for (int i = liste.size()-1; i>=0;i--){ + System.out.println("arguments:"+i+":"+liste.get(i)); + System.out.println(liste.get(i).getClass()); + } + } */ + + return wanted_type; // Vi skal ikke tjekke dette, da vi ikke kan vide det. Fordi det er en runtime ting } public Type relationOperatorTypeCheck(RelationsAndLogicalOperatorNode node) { @@ -355,7 +383,7 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { String identifier = node.getIdentifier().toString(); Type variableType = getType(node.getType()); // Left side type - + wanted_type = variableType; AstNode ass = node.getValue(); // THis is right side should be a node Type assignmentType = getType(ass); // This should give right side type @@ -369,6 +397,7 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { + " And that is hella iligal"); } + wanted_type =Type.UNKNOWN; } else { throw new RuntimeException("variable: " + node.getIdentifier() + " already exists in the scope"); } @@ -381,12 +410,11 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { public Type getVariable(IdentifierNode node) { if (scopes.getLast().containsKey(node.getIdentifier().toString())) { - // System.out.println("234324234"+scopes.getFirst()); + currentIdentifierCheck = node.getIdentifier().toString(); return scopes.getLast().get(node.getIdentifier().toString()); } - // System.out.println("We get in here:"+node.getIdentifier().toString()); - // System.out.println("The scopes:"+scopes); + for (int i = activeScope.getLast(); i < scopes.size(); i++) { if (scopes.get(i).containsKey(node.getIdentifier().toString())) { currentIdentifierCheck = node.getIdentifier().toString(); @@ -394,15 +422,14 @@ public Type getVariable(IdentifierNode node) { } } errorHandler("could not find the variable " + node.getIdentifier()); - // throw new RuntimeException("could not find the variable " + - // node.getIdentifier()); + return Type.UNKNOWN; } // Check if return = type er det samme som den function den står i. public void visitReturnNode(ReturnStatementNode node) { Type returnType = getType(node.getReturnValue()); - // System.out.println(returnType); + if (currentActiveFunction == "") { errorHandler("You have made return statement outside a function THAT IS illigal"); } else { @@ -419,18 +446,13 @@ public void visitReturnNode(ReturnStatementNode node) { } public void visitAssignNode(AssignmentNode node) { - + boolean foundIdentifier = false; for (int i = scopes.size() - 1; 0 <= i; i--) { - // System.out.println("This many scopes:" + i + ":" + scopes.get(i)); + HashMap ETable = scopes.get(i); - // System.out.println("Scopes:"+scopes+"CurrentScopeWecheck:"); - // System.out.println("Here it break2s"+ETable); - if (true) { - // System.out.println("Identifier" + node.getIdentifier().toString()); - // System.out.println("Etable:" + ETable); - } + if (ETable.containsKey(node.getIdentifier().toString())) {// hvis x er i scope foundIdentifier = true; // tjekke om det er lovligt. @@ -528,8 +550,7 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { visitBlockNode(node.getBlock());// Alle statement i fn. En af dem er returnStatement currentActiveFunction = ""; if (!hasReturnStatement && Type.VOID != getType(node.getReturnType())) { - // System.out.println(getType(node.getReturnType())); - // System.out.println(typeOfReturnFunction); + errorHandler("Missing return statement in function declartion:" + node.getIdentifier().toString()); } hasReturnStatement = false; @@ -580,38 +601,102 @@ public void visitFunctionCall(FunctionCallNode node) { } /* - * Check om den eksistere - * Deklerere den til sidst. fordi kun vis alle variabler i den er okay - * check variabler - * hvis de ok gem dem i hashmap - * Skal også tjekke type af Struct i guess + * Vi skal tjekke alle hashmasps med structs for at se om den eksistere i + * forvejen + * Vi skal gemme structet i den rigtige type hashmap. + * Tjekke alle variable statements + * Vis nogen fejler skal Struct ikke gemmes i hashmap */ - public void visitStruct(StructureDefinitionNode node) { - String identifier = node.getIdentifier().toString(); - if (!structVariablesTable.containsKey(identifier)) { + public void visitStruct(StructureDefinitionNode node) {// ! FORKERT SKAL ÆNDRES - Type structType = getType(node.getType()); + // Først skal vi hente typen som der ønskes at blive deklereet + String typeStruct = node.getType().toString(); + + if (!structTypes.containsKey(typeStruct)) { - HashMap localETable = new HashMap<>(); + if (typeStruct.equals("enemy")) { + // Nu har vi typen, så skal vi hente identifieren på structet + String identifier = node.getIdentifier().toString(); + + // Nu kender vi identiferen, nu skal vi bare tjekke om den eksistere i hashmap + if (!tileInformationEnemy.containsKey(identifier)) { + // Vis den ikke eksisterer skal vi deklere den, efter vi har tjekke variabler + + // Laver et "Scope" vi kan gemme variablerne i undervejs + HashMap localETable = new HashMap<>(); + scopes.add(localETable); + // Henter alle declarations + List declarations = node.getVariableDeclarations(); + struct_variable_declarion_failed = false;// Bool til at holde styr på om en deklaration fejler + // Looper over alle declarationerne og gemmer dem i localEtable + for (VariableDeclarationNode declaration : declarations) { + visitVariableDeclarationforStructs(declaration); + } + // Vis så ingen declarationer fejler skal vi gemme variablerne(Etable) med + // structet + if (!struct_variable_declarion_failed) { + tileInformationEnemy.put(identifier, localETable); + structTypes.put(identifier, Type.ENEMY); + } + struct_variable_declarion_failed = false; + scopes.remove(localETable); + } else { + // Smide fejl vis vi prøver at redeklere + errorHandler("Struct " + node.getIdentifier().toString() + " already exists"); + } + } + // Repeat bare med andre typper + if (typeStruct.equals("floor")) { + String identifier = node.getIdentifier().toString(); + if (!tileInformationFloor.containsKey(identifier)) { + HashMap localETable = new HashMap<>(); + scopes.add(localETable); + List declarations = node.getVariableDeclarations(); + struct_variable_declarion_failed = false; + + for (VariableDeclarationNode declaration : declarations) { + visitVariableDeclarationforStructs(declaration); + } - scopes.add(localETable); + if (!struct_variable_declarion_failed) { + tileInformationFloor.put(identifier, localETable); + structTypes.put(identifier, Type.FLOOR); + } + struct_variable_declarion_failed = false; + scopes.remove(localETable); + } else { - List declarations = node.getVariableDeclarations(); - struct_variable_declarion_failed = false; - for (VariableDeclarationNode declaration : declarations) { - visitVariableDeclarationforStructs(declaration); - } - if (!struct_variable_declarion_failed) { - structTypes.put(identifier, structType); - structVariablesTable.put(identifier, localETable); + errorHandler("Struct " + node.getIdentifier().toString() + " already exists"); + } } + if (typeStruct.equals("wall")) { + String identifier = node.getIdentifier().toString(); - struct_variable_declarion_failed = false; - scopes.remove(localETable); + if (!tileInformationWall.containsKey(identifier)) { + HashMap localETable = new HashMap<>(); + scopes.add(localETable); + + List declarations = node.getVariableDeclarations(); + struct_variable_declarion_failed = false; + + for (VariableDeclarationNode declaration : declarations) { + visitVariableDeclarationforStructs(declaration); + } + if (!struct_variable_declarion_failed) { + tileInformationWall.put(identifier, localETable); + structTypes.put(identifier, Type.WALL); + } + struct_variable_declarion_failed = false; + scopes.remove(localETable); + } else { + errorHandler("Struct " + node.getIdentifier().toString() + " already exists"); + } + } } else { errorHandler("Struct " + node.getIdentifier().toString() + " already exists"); } + } private void visitVariableDeclarationforStructs(VariableDeclarationNode node) { @@ -671,7 +756,7 @@ public Type getType(Object node) { } else if (node instanceof PropertyAccessNode) { type = visitPropertyAccessNode((PropertyAccessNode) node); } else if (node instanceof MethodCallNode) { - visitMethodCall((MethodCallNode) node); + type = visitMethodCall((MethodCallNode) node); } else if (node instanceof BinaryOperatorNode) { type = binaryOperatorTypeCheck((BinaryOperatorNode) node); } else if (node instanceof RelationsAndLogicalOperatorNode) { diff --git a/test.carl b/test.carl index fe03cc0..ec67715 100644 --- a/test.carl +++ b/test.carl @@ -1,28 +1,24 @@ -var x: int = 0 -var y: int = 42 +var Goblin : enemy ={ + var difficulty : int = 1 + var health : int = 500 + var symbol : string= "O" + + } -fn p() -> void { - x= x + 3 -} -fn q() -> void { - p() -} -fn main() -> int { - x=20 - print(x) - var x : int = 9 - - q() - y = x - return y +var Hejman :floor ={ + var difficulty : int = 1 + var health : int = 500 + var symbol : string= "O" } -print("Før main") -var v : int = main() -print("efter Main") +var nejman :wall ={ + var difficulty : int = 1 + var health : int = 500 + var symbol : string= "O" +} -print(y) -print(v) +var i : int = enemy.get(0).symbol +print(i) From b71b299132264a81957c4cc3b2d783fcbcb7bec2 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Thu, 16 May 2024 13:28:10 +0200 Subject: [PATCH 76/94] Methods assignemnt typer bliver nu resolvet --- .../carl/Interpreter/EvaluatorExecutor.java | 6 +++--- .../cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java index 6ac0c42..c8637ee 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java @@ -296,7 +296,7 @@ public void visit(AssignmentNode node) { } else { from = scopes.size() - 1; } - System.out.println(from); + //System.out.println(from); for (int i = from; i >= 0; i--) { if (scopes.get(i).containsKey(node.getIdentifier().toString())) { AstNode nodeToChange = scopes.get(i).get(node.getIdentifier().toString()); @@ -337,9 +337,9 @@ public void visit(VariableDeclarationNode node) { wantedType = Type.FLOAT; } - System.out.println("Wanted type in methodCall node:" + wantedType); + toChange = visit((MethodCallNode) toChange); - System.out.println(toChange.getClass()); + Type tochange_Type = Type.UNKNOWN; if (toChange instanceof IntNode) { tochange_Type = Type.INT; diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java index 190a9f5..d87c5eb 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java @@ -169,6 +169,7 @@ public void visistArrayAssignment(ArrayAssignmentNode node) { if (scopes.get(i).containsKey(identifier)) { found = true; arrayType = scopes.get(i).get(identifier); + wanted_type=arrayType; } } if (found) { @@ -254,6 +255,7 @@ public void visistarrayDekleration(ArrayDefinitionNode node) { public void visitPropertyAssignment(PropertyAssignmentNode node) { Type oldType = visitPropertyAccessNode(node.getPropertyAccessNode()); + wanted_type = oldType; Type newType = getType(node.getValue()); errorHandler(oldType + " " + newType); if (oldType != newType) { @@ -392,6 +394,8 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { Type variableType = getType(node.getType()); // Left side type wanted_type = variableType; AstNode ass = node.getValue(); // THis is right side should be a node + + Type assignmentType = getType(ass); // This should give right side type if (variableType == assignmentType) { @@ -399,6 +403,9 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { scopes.getLast().put(node.getIdentifier().toString(), typeWeSaveInETable); } else { + + + errorHandler("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + " that has the type:" + variableType + " And that is hella iligal"); @@ -469,9 +476,10 @@ public void visitAssignNode(AssignmentNode node) { String identifier = node.getIdentifier().toString(); Type rightType = getType(node.getValue()); - + wanted_type = oldType; // tjekke om det er lovligt. if (oldType != rightType) { + errorHandler("Tryied to asssign Type:" + rightType + " to the variable:" + identifier + " that has the type:" + oldType + " And that is hella iligal"); From edea15c4b84037af4a9280061d06879536d9089d Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Thu, 16 May 2024 13:53:57 +0200 Subject: [PATCH 77/94] Jeg har myrtet Active Scope fra alt Og ALT VIRKER --- .../carl/Interpreter/EvaluatorExecutor.java | 96 ++++--------------- .../carl/Interpreter/InbuildClasses.java | 17 +--- .../java/dk/aau/cs_24_sw_4_16/carl/Main.java | 5 +- .../carl/Semantic_A/SemanticChecker.java | 10 +- 4 files changed, 26 insertions(+), 102 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java index c8637ee..bdb8379 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java @@ -10,7 +10,7 @@ public class EvaluatorExecutor { HashMap fTable; HashMap vTable; Stack> scopes; - Deque activeScope; + HashMap> tileInformationEnemy; HashMap> tileInformationFloor; HashMap> tileInformationWall; @@ -30,7 +30,7 @@ public EvaluatorExecutor() { tileInformationFloor = new HashMap<>(); tileInformationWall = new HashMap<>(); scopes = new Stack<>(); - activeScope = new ArrayDeque<>(); + // activeScope.push(0); scopes.add(vTable); rooms = new ArrayList<>(); @@ -250,69 +250,30 @@ public void visit(IfStatementNode node) { } public AstNode getVariable(IdentifierNode node) { - // for (HashMap vTable : scopes) { - - int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; - for (int i = scopes.size() - 1; i >= towards; i--) { - if (scopes.get(i).containsKey(node.getIdentifier())) { - return scopes.get(i).get(node.getIdentifier()); - } - } - int from = 0; - if (!activeScope.isEmpty()) { - from = activeScope.getFirst() - 1; - } else { - from = scopes.size() - 1; - } - for (int i = from; i >= 0; i--) { + + for (int i = scopes.size()-1; i >= 0; i--) { if (scopes.get(i).containsKey(node.getIdentifier())) { return scopes.get(i).get(node.getIdentifier()); } } - // if (scopes.getFirst().containsKey(node.getIdentifier())) { - // return scopes.getFirst().get(node.getIdentifier()); - // } + throw new RuntimeException("could not find the variable " + node.getIdentifier()); } public void visit(AssignmentNode node) { - // System.out.println("fycj me"+node); - int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; - // System.out.println(towards+":"+activeScope.getLast()); + for (int i = scopes.size() - 1; i >= 0; i--) { - // System.out.println(scopes.get(i)+i); + if (scopes.get(i).containsKey(node.getIdentifier().getIdentifier())) { - // if (vTable.containsKey(node.getIdentifier().toString())) { - AstNode nodeToChange = scopes.get(i).get(node.getIdentifier().toString()); - AstNode toChange = node.getValue(); - replaceValue(nodeToChange, toChange); - return; - } - } - int from = 0; - if (!activeScope.isEmpty()) { - from = activeScope.getFirst() - 1; - } else { - from = scopes.size() - 1; - } - //System.out.println(from); - for (int i = from; i >= 0; i--) { - if (scopes.get(i).containsKey(node.getIdentifier().toString())) { + AstNode nodeToChange = scopes.get(i).get(node.getIdentifier().toString()); AstNode toChange = node.getValue(); replaceValue(nodeToChange, toChange); return; } } - // if (scopes.getFirst().containsKey(node.getIdentifier().toString())) { - // AstNode nodeToChange = - // scopes.getFirst().get(node.getIdentifier().toString()); - // AstNode toChange = node.getValue(); - // replaceValue(nodeToChange, toChange); - // return; - // } - + throw new RuntimeException("Variable '" + node.getIdentifier() + "' has not been defined yet."); } @@ -500,37 +461,14 @@ public void visit(ArrayDefinitionNode node) { private boolean idExists(String id) { boolean found = false; - int towards = !activeScope.isEmpty() ? activeScope.getLast() : 0; - for (int i = scopes.size() - 1; i >= towards; i--) { - if (scopes.get(i).containsKey(id)) { - found = true; - } - } - int from = 0; - if (!activeScope.isEmpty()) { - from = activeScope.getFirst() - 1; - } else { - from = scopes.size() - 1; - } - for (int i = from; i >= 0; i--) { + + for (int i = scopes.size()-1; i >= 0; i--) { if (scopes.get(i).containsKey(id)) { found = true; } } - // if (scopes.getFirst().containsKey(id)) { - // found = true; - // } - - // if (scopes.getFirst().containsKey(id)) { - // found = true; - // } - // - // for (int i = activeScope.getLast(); i < scopes.size(); i++) { - // if (scopes.get(i).containsKey(id)) { - // found = true; - // } - // } - + + return found; } @@ -559,7 +497,7 @@ public AstNode visit(ProgramNode node) { public AstNode visit(FunctionCallNode node) { if (node.getFunctionName().toString().equals("print")) { - InbuildClasses.print(node, scopes, activeScope); + InbuildClasses.print(node, scopes); } else if (node.getFunctionName().toString().equals("generateMap")) { InbuildClasses.generateGrid(node, scopes, tileInformationWall); @@ -585,7 +523,7 @@ public AstNode visit(FunctionCallNode node) { // Boolean returnVoidCase = false; HashMap localTable = new HashMap<>(); scopes.add(localTable); - activeScope.add(scopes.size() - 1); + if (fTable.containsKey(node.getFunctionName().toString())) { FunctionDefinitionNode function = fTable.get(node.getFunctionName().toString()); List arguments = function.getArguments().getParameters(); @@ -602,7 +540,7 @@ public AstNode visit(FunctionCallNode node) { returnValue = getVariable((IdentifierNode) returnValue); } scopes.remove(localTable); - activeScope.removeLast(); + if (function.getReturnType().getType().equals("void")) { if (returnValue != null) { throw new RuntimeException( @@ -615,7 +553,7 @@ public AstNode visit(FunctionCallNode node) { } scopes.remove(localTable); - activeScope.removeLast(); + } return node; } diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java index 14e0c04..640d104 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java @@ -9,7 +9,7 @@ import java.util.*; public class InbuildClasses { - public static void print(FunctionCallNode node, Stack> scopes, Deque activeScope) { + public static void print(FunctionCallNode node, Stack> scopes) { // System.out.println("We get in here"); StringBuilder toPrint = new StringBuilder(); for (AstNode argument : node.getArguments()) { @@ -26,20 +26,7 @@ public static void print(FunctionCallNode node, Stack> } } - if (!found) { - int from = 0; - if (!activeScope.isEmpty()) { - from = activeScope.getFirst(); - } else { - from = scopes.size() - 1; - } - for (int i = from; i >= 0; i--) { - if (scopes.get(i).containsKey(argument.toString())) { - toPrint.append(scopes.getFirst().get(argument.toString()).toString()).append(" "); - } - } - - } + } else if (argument instanceof FloatNode) { System.out.println("We get in Floatnode"); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index 8a01729..9ca4f86 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -18,7 +18,7 @@ public static void main(String... args) { * Java libary takes in filepath, reads file into memory. Can now be acced * throught identifier fileinput */ - FileInputStream fileInput = new FileInputStream("test2.carl"); + FileInputStream fileInput = new FileInputStream("test.carl"); // CARLLexer is a generated lexer class for the CARL language. // It tokenizes the input stream (breaks the input into meaningful pieces called // tokens). @@ -46,10 +46,11 @@ public static void main(String... args) { SemanticChecker typeChecker = new SemanticChecker(); typeChecker.visitor(astRoot); - + System.out.println("yes"); if (!typeChecker.thereWasAnError) { EvaluatorExecutor inter = new EvaluatorExecutor(); inter.visit(astRoot); + } // Interpreter is a class that can traverse the AST and interpret or execute the // program based on the AST. diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java index d87c5eb..0ac005d 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java @@ -16,7 +16,6 @@ public class SemanticChecker { HashMap eTable;// variable table, identifier(x) og node(int) Stack> scopes; // scope table, variable identifier(x) og node - Deque activeScope;// Hvilket scope vi er i nu int errorNumber = 1; Boolean printDebugger = false; Boolean hasReturnStatement = false; @@ -38,8 +37,7 @@ public SemanticChecker() { // fTable = new HashMap<>(); eTable = new HashMap<>(); scopes = new Stack<>(); - activeScope = new ArrayDeque<>(); - activeScope.push(0); + scopes.add(eTable); typeOfReturnFunction = new HashMap<>(); functionParameters = new HashMap<>(); @@ -123,7 +121,7 @@ public void visistArrayAccesNodeFn(ArrayAccessNode node) { String identifier = node.getIdentifier().toString(); boolean found = scopes.getFirst().containsKey(identifier); - for (int i = activeScope.getLast(); i < scopes.size(); i++) { + for (int i = scopes.size()-1; i >= 0; i--) { if (scopes.get(i).containsKey(identifier)) { found = true; } @@ -217,7 +215,7 @@ public void visistarrayDekleration(ArrayDefinitionNode node) { String identifier = node.getIdentifier().toString(); boolean found = scopes.getFirst().containsKey(identifier); - for (int i = activeScope.getLast(); i < scopes.size(); i++) { + for (int i = scopes.size()-1; i >= 0; i--) { if (scopes.get(i).containsKey(identifier)) { found = true; } @@ -429,7 +427,7 @@ public Type getVariable(IdentifierNode node) { return scopes.getLast().get(node.getIdentifier().toString()); } - for (int i = activeScope.getLast(); i < scopes.size(); i++) { + for (int i = scopes.size()-1; i >= 0; i--) { if (scopes.get(i).containsKey(node.getIdentifier().toString())) { currentIdentifierCheck = node.getIdentifier().toString(); return scopes.get(i).get(node.getIdentifier().toString()); From af43f2ce6decd1f11fffcd3c8d04a4c9403fb99c Mon Sep 17 00:00:00 2001 From: MShadiF Date: Thu, 16 May 2024 14:07:22 +0200 Subject: [PATCH 78/94] =?UTF-8?q?Fjernede=20system.out.print=20og=20retted?= =?UTF-8?q?e=20s=C3=A5=20monster=20ogs=C3=A5=20spawner=20i=20alle=20mulige?= =?UTF-8?q?=20rooms?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java index 7f5fdff..9018ef6 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/InbuildClasses.java @@ -10,7 +10,6 @@ public class InbuildClasses { public static void print(FunctionCallNode node, Stack> scopes, Deque activeScope) { - // System.out.println("We get in here"); StringBuilder toPrint = new StringBuilder(); for (AstNode argument : node.getArguments()) { if (argument instanceof StatementNode) { @@ -42,10 +41,8 @@ public static void print(FunctionCallNode node, Stack> } } else if (argument instanceof FloatNode) { - System.out.println("We get in Floatnode"); toPrint.append(((FloatNode) argument).getValue()); } else if (argument instanceof IntNode) { - System.out.println("We get in Intnode"); toPrint.append(((IntNode) argument).getValue()); } else if (argument instanceof StringNode) { toPrint.append(((StringNode) argument).getValue()); @@ -159,21 +156,18 @@ public static void generateCorridors(FunctionCallNode node, Stack> scopes, HashMap> tileInformationEnemy, List> rooms) { ArrayNode map = ((ArrayNode) scopes.getFirst().get("map")); - System.out.println(tileInformationEnemy); if (!node.getArguments().isEmpty()) { if(node.getArguments().size() == 1 && node.getArguments().get(0) instanceof IntNode) { int difficulty = ((IntNode) node.getArguments().get(0)).getValue(); while (difficulty > 0) { - int roomSpawn = EvaluatorExecutor.rand.nextInt(0,rooms.size() - 2); + int roomSpawn = EvaluatorExecutor.rand.nextInt(0,rooms.size() - 1); int x = EvaluatorExecutor.rand.nextInt(((IntNode) rooms.get(roomSpawn).get("x")).getValue(), (((IntNode) rooms.get(roomSpawn).get("x")).getValue() + ((IntNode) rooms.get(roomSpawn).get("width")).getValue())); int y = EvaluatorExecutor.rand.nextInt(((IntNode) rooms.get(roomSpawn).get("y")).getValue(), (((IntNode) rooms.get(roomSpawn).get("y")).getValue() + ((IntNode) rooms.get(roomSpawn).get("height")).getValue())); var key = tileInformationEnemy.keySet().toArray()[EvaluatorExecutor.rand.nextInt(0,tileInformationEnemy.size())]; StringNode symbol = ((StringNode) tileInformationEnemy.get(key).get("symbol")); int difficultyMonster = ((IntNode) tileInformationEnemy.get(key).get("difficulty")).getValue(); - System.out.println(difficultyMonster); if (difficulty >= difficultyMonster) { if (((StringNode) map.get(y,x)).getValue().equals("f")) { - System.out.println("Hello"); map.set(new StringNode(symbol.getValue()), y, x); difficulty -= difficultyMonster; } From 4916d2bc15364bbb066041521b69c244bf7a1052 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sun, 19 May 2024 11:58:21 +0200 Subject: [PATCH 79/94] Update Main.java Fjernede en System out som havde sneget sig ind i main --- src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index 9ca4f86..6625b83 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -46,7 +46,7 @@ public static void main(String... args) { SemanticChecker typeChecker = new SemanticChecker(); typeChecker.visitor(astRoot); - System.out.println("yes"); + if (!typeChecker.thereWasAnError) { EvaluatorExecutor inter = new EvaluatorExecutor(); inter.visit(astRoot); From 12b58f73953ab4a0cb91a49a1645dd9e9b19e128 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sun, 19 May 2024 15:01:30 +0200 Subject: [PATCH 80/94] =?UTF-8?q?S=C3=A5=20f=C3=A5r=20vi=20ikke=20l=C3=A6n?= =?UTF-8?q?gere=20fejl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../carl/Semantic_A/SemanticChecker.java | 130 +++++++----------- test.carl | 26 +--- 2 files changed, 56 insertions(+), 100 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java index 9940c81..0e8217b 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java @@ -30,14 +30,14 @@ public class SemanticChecker { HashMap> tileInformationWall; List> rooms; HashMap> structVariablesTable; - Type wanted_type =Type.UNKNOWN; + Type wanted_type = Type.UNKNOWN; public SemanticChecker() { // fTable = new HashMap<>(); eTable = new HashMap<>(); scopes = new Stack<>(); - + scopes.add(eTable); typeOfReturnFunction = new HashMap<>(); functionParameters = new HashMap<>(); @@ -99,18 +99,17 @@ public void visitStatements(StatementNode node) { visitPropertyAssignment((PropertyAssignmentNode) node.getNode()); } if (node.getNode() instanceof MethodCallNode) { - // errorHandler("ewjrngkewgjewkejnweklrglewrkngewkrgkwen"); - //visitMethodCall((MethodCallNode) node.getNode()); + // errorHandler("ewjrngkewgjewkejnweklrglewrkngewkrgkwen"); + // visitMethodCall((MethodCallNode) node.getNode()); } } public void errorHandler(String errorMessage) { thereWasAnError = true; - - System.err.println("Error " + errorNumber); - errorNumber = errorNumber + 1; - System.err.println(errorMessage); - + + System.err.println("Error " + errorNumber); + errorNumber = errorNumber + 1; + System.err.println(errorMessage); } @@ -121,7 +120,7 @@ public void visistArrayAccesNodeFn(ArrayAccessNode node) { String identifier = node.getIdentifier().toString(); boolean found = scopes.getFirst().containsKey(identifier); - for (int i = scopes.size()-1; i >= 0; i--) { + for (int i = scopes.size() - 1; i >= 0; i--) { if (scopes.get(i).containsKey(identifier)) { found = true; } @@ -161,13 +160,12 @@ public void visistArrayAssignment(ArrayAssignmentNode node) { Type arrayType = Type.UNKNOWN; found = scopes.getLast().containsKey(identifier); - for (int i = scopes.size() - 1; 0 <= i; i--) { if (scopes.get(i).containsKey(identifier)) { found = true; arrayType = scopes.get(i).get(identifier); - wanted_type=arrayType; + wanted_type = arrayType; } } if (found) { @@ -190,12 +188,16 @@ public void visistArrayAssignment(ArrayAssignmentNode node) { } if (!validTypesaccesTypes) { errorHandler("Tried to assign the array:" + identifier + " but acces value: " + arguementNumber - + " is of type:" + sizeType + " and should be:" + arrayType); + + " is of type:" + sizeType + " and should be:" + "Int"); } // Tjek venstre mod højre Type assignType = getType(node.getValue()); - if (arrayType != assignType) { + if (arrayType == assignType) { + + } else if (assignType == Type.INT && arrayType == Type.FLOAT) { + + } else { errorHandler("Tried to assign the type:" + assignType + " to the array:" + identifier + " that has the type:" + arrayType + ", and that is ilegal"); } @@ -215,7 +217,7 @@ public void visistarrayDekleration(ArrayDefinitionNode node) { String identifier = node.getIdentifier().toString(); boolean found = scopes.getFirst().containsKey(identifier); - for (int i = scopes.size()-1; i >= 0; i--) { + for (int i = scopes.size() - 1; i >= 0; i--) { if (scopes.get(i).containsKey(identifier)) { found = true; } @@ -261,7 +263,6 @@ public void visitPropertyAssignment(PropertyAssignmentNode node) { } } - public Type visitPropertyAccessNode(PropertyAccessNode node) { List validPropertyAccess = new ArrayList<>(Arrays.asList("size", "get")); String firstIdentifier = node.getIdentifiers().get(0).toString(); @@ -284,39 +285,10 @@ public Type visitPropertyAccessNode(PropertyAccessNode node) { return Type.UNKNOWN; } - public Type visitMethodCall(MethodCallNode node) { // - // Her skal vi først finde ud af vilken type struct vi skal lede i - // Så skal vi finde ud af om structet eksistere - // Så skal vi indexe og tjekke dens typer imod den type ting itng - - /* String identifier = node.getIdentifierNode().toString(); - System.out.println("Identifier:"+identifier); // Variable vi leder efter i struct - - PropertyAccessNode propertyAccessNode = node.getPropertyAccessContext(); - System.out.println("Propertyascc:"+propertyAccessNode); - - String list = propertyAccessNode.getList(); - List identifiernodes = propertyAccessNode.getIdentifiers(); - System.out.println("Liste:"+list);// Type af struct hasmap vi skal kikke i - System.out.println("Identifiernodes"+identifiernodes); - - for (int i = identifiernodes.size()-1; i>=0;i--){ - System.out.println("Identifiernode:"+i+":"+identifiernodes.get(i)); - } - - if (node.getValue() instanceof ArgumentListNode) { - // Cast node to ArgumentListNode - ArgumentListNode argumentListNode = (ArgumentListNode) node.getValue(); - // You can now use argumentListNode for further operations - System.out.println(argumentListNode); - List liste = argumentListNode.getList(); - for (int i = liste.size()-1; i>=0;i--){ - System.out.println("arguments:"+i+":"+liste.get(i)); - System.out.println(liste.get(i).getClass()); - } - } */ + public Type visitMethodCall(MethodCallNode node) { // - return wanted_type; // Vi skal ikke tjekke dette, da vi ikke kan vide det. Fordi det er en runtime ting + return wanted_type; // Vi skal ikke tjekke dette, da vi ikke kan vide det. Fordi det er en runtime + // ting } public Type relationOperatorTypeCheck(RelationsAndLogicalOperatorNode node) { @@ -336,11 +308,9 @@ public Type relationOperatorTypeCheck(RelationsAndLogicalOperatorNode node) { return Type.BOOLEAN; } else if (leftType == Type.BOOLEAN && rightType == Type.BOOLEAN) { return Type.BOOLEAN; - } - else if (leftType == Type.STRING && rightType == Type.STRING) { + } else if (leftType == Type.STRING && rightType == Type.STRING) { return Type.BOOLEAN; } - errorHandler("Wrong types for relation operation:" + leftType + ":" + left + " And:" + right + ":" + rightType); @@ -392,24 +362,25 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { Type variableType = getType(node.getType()); // Left side type wanted_type = variableType; AstNode ass = node.getValue(); // THis is right side should be a node - - + Type assignmentType = getType(ass); // This should give right side type if (variableType == assignmentType) { Type typeWeSaveInETable = variableType; scopes.getLast().put(node.getIdentifier().toString(), typeWeSaveInETable); + } else if (variableType == Type.FLOAT && assignmentType == Type.INT) { + Type typeWeSaveInETable = variableType; + scopes.getLast().put(node.getIdentifier().toString(), typeWeSaveInETable); + } else { - - - errorHandler("Tryied to asssign Type:" + assignmentType + " to the variable:" + identifier + errorHandler("Tryied to declare Type:" + assignmentType + " to the variable:" + identifier + " that has the type:" + variableType + " And that is hella iligal"); } - wanted_type =Type.UNKNOWN; + wanted_type = Type.UNKNOWN; } else { throw new RuntimeException("variable: " + node.getIdentifier() + " already exists in the scope"); } @@ -422,12 +393,12 @@ private void visitVariableDeclaration(VariableDeclarationNode node) { public Type getVariable(IdentifierNode node) { if (scopes.getLast().containsKey(node.getIdentifier().toString())) { - + currentIdentifierCheck = node.getIdentifier().toString(); return scopes.getLast().get(node.getIdentifier().toString()); } - - for (int i = scopes.size()-1; i >= 0; i--) { + + for (int i = scopes.size() - 1; i >= 0; i--) { if (scopes.get(i).containsKey(node.getIdentifier().toString())) { currentIdentifierCheck = node.getIdentifier().toString(); return scopes.get(i).get(node.getIdentifier().toString()); @@ -441,7 +412,7 @@ public Type getVariable(IdentifierNode node) { // Check if return = type er det samme som den function den står i. public void visitReturnNode(ReturnStatementNode node) { Type returnType = getType(node.getReturnValue()); - + if (currentActiveFunction == "") { errorHandler("You have made return statement outside a function THAT IS illigal"); } else { @@ -462,10 +433,9 @@ public void visitAssignNode(AssignmentNode node) { boolean foundIdentifier = false; for (int i = scopes.size() - 1; 0 <= i; i--) { - + HashMap ETable = scopes.get(i); - - + if (ETable.containsKey(node.getIdentifier().toString())) {// hvis x er i scope foundIdentifier = true; // tjekke om det er lovligt. @@ -476,17 +446,18 @@ public void visitAssignNode(AssignmentNode node) { Type rightType = getType(node.getValue()); wanted_type = oldType; // tjekke om det er lovligt. - if (oldType != rightType) { - - errorHandler("Tryied to asssign Type:" + rightType + " to the variable:" + identifier + if (oldType == rightType) { + + } else if (oldType == Type.FLOAT && rightType == Type.INT) { + + } else { + errorHandler("Tried to asssign Type:" + rightType + " to the variable:" + identifier + " that has the type:" + oldType + " And that is hella iligal"); - } - } else { - } - if (foundIdentifier) { - break; + if (foundIdentifier) { + break; + } } } if (!foundIdentifier) { @@ -528,12 +499,12 @@ public void visitWhileLoop(WhileLoopNode node) { HashMap localTable = new HashMap<>(); scopes.add(localTable); visitBlockNode(node.getBlock()); - + scopes.remove(localTable); } public void visitFunctionDefinition(FunctionDefinitionNode node) { - + if (!listOfInbuiltFunctions.contains(node.getIdentifier().toString())) { if (!typeOfReturnFunction.containsKey(node.toString()) && !functionParameters.containsKey(node.toString())) { @@ -564,7 +535,7 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { visitBlockNode(node.getBlock());// Alle statement i fn. En af dem er returnStatement currentActiveFunction = ""; if (!hasReturnStatement && Type.VOID != getType(node.getReturnType())) { - + errorHandler("Missing return statement in function declartion:" + node.getIdentifier().toString()); } hasReturnStatement = false; @@ -585,7 +556,7 @@ public void visitFunctionDefinition(FunctionDefinitionNode node) { * Vi skal sige hvis arguemtnet er en forkert type. */ public void visitFunctionCall(FunctionCallNode node) { - + if (!listOfInbuiltFunctions.contains(node.getFunctionName().toString())) { HashMap localETable = new HashMap<>(); @@ -625,13 +596,13 @@ public void visitStruct(StructureDefinitionNode node) {// ! FORKERT SKAL ÆNDRES // Først skal vi hente typen som der ønskes at blive deklereet String typeStruct = node.getType().toString(); - + if (!structTypes.containsKey(typeStruct)) { if (typeStruct.equals("enemy")) { // Nu har vi typen, så skal vi hente identifieren på structet String identifier = node.getIdentifier().toString(); - + // Nu kender vi identiferen, nu skal vi bare tjekke om den eksistere i hashmap if (!tileInformationEnemy.containsKey(identifier)) { // Vis den ikke eksisterer skal vi deklere den, efter vi har tjekke variabler @@ -843,8 +814,7 @@ public Type getType(Object node) { default: break; } - } - else { + } else { errorHandler("The node we get failed to handle:" + node.getClass()); } return type; diff --git a/test.carl b/test.carl index ec67715..fc91ed4 100644 --- a/test.carl +++ b/test.carl @@ -1,24 +1,10 @@ -var Goblin : enemy ={ - var difficulty : int = 1 - var health : int = 500 - var symbol : string= "O" - - } +var carl:float = 2 +print(carl) -var Hejman :floor ={ - var difficulty : int = 1 - var health : int = 500 - var symbol : string= "O" -} +carl =234234 -var nejman :wall ={ - var difficulty : int = 1 - var health : int = 500 - var symbol : string= "O" -} +var size : int = 20 +var map : float[size][size] - - -var i : int = enemy.get(0).symbol -print(i) +map[2][2] =4.5 \ No newline at end of file From 680080664099731a649c69068578c0ecaf68a9bc Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Sun, 19 May 2024 15:03:50 +0200 Subject: [PATCH 81/94] Rettede lige en lille fejl --- .../aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index 11a9548..8ac12cb 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -111,7 +111,7 @@ void testTypeCheker47() { Error 1 Wrong types for binary operation:INT:integer And:test_string:STRING Error 2 - Tryied to asssign Type:UNKNOWN to the variable:result that has the type:INT And that is hella iligal + Tryied to declare Type:UNKNOWN to the variable:result that has the type:INT And that is hella iligal """; SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); @@ -233,7 +233,7 @@ void testTypeCheker2() { Error 1 Tried to assign the type:STRING to the array:array that has the type:INT, and that is ilegal Error 2 - Tried to assign the array:array but acces value: 0 is of type:STRING and should be:INT + Tried to assign the array:array but acces value: 0 is of type:STRING and should be:Int """; SemanticChecker.visitor(astTree); @@ -320,7 +320,7 @@ void testTypeCheker11() { String correct_error = """ Error 1 - Tryied to asssign Type:INT to the variable:test_variable2 that has the type:STRING And that is hella iligal"""; + Tryied to declare Type:INT to the variable:test_variable2 that has the type:STRING And that is hella iligal"""; SemanticChecker.visitor(astTree); String terminal_Errors = normalizeOutput(); assertEquals(correct_error.trim(), terminal_Errors); From 976639a30f9e9c88851330cd0731ab557bb807fa Mon Sep 17 00:00:00 2001 From: MShadiF Date: Mon, 20 May 2024 12:23:09 +0200 Subject: [PATCH 82/94] Rettede if-statements --- .../carl/Semantic_A/SemanticChecker.java | 15 ++++----------- .../carl/Semantic_A/TypeCheckerTest.java | 2 +- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java index 0e8217b..07b00ad 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/SemanticChecker.java @@ -193,15 +193,12 @@ public void visistArrayAssignment(ArrayAssignmentNode node) { // Tjek venstre mod højre Type assignType = getType(node.getValue()); - if (arrayType == assignType) { - - } else if (assignType == Type.INT && arrayType == Type.FLOAT) { - - } else { + if (!(arrayType == assignType || (assignType == Type.INT && arrayType == Type.FLOAT))) { errorHandler("Tried to assign the type:" + assignType + " to the array:" + identifier - + " that has the type:" + arrayType + ", and that is ilegal"); + + " that has the type:" + arrayType + ", and that is illegal"); } + } else { errorHandler("Array:" + identifier + " Does not exist "); } @@ -446,11 +443,7 @@ public void visitAssignNode(AssignmentNode node) { Type rightType = getType(node.getValue()); wanted_type = oldType; // tjekke om det er lovligt. - if (oldType == rightType) { - - } else if (oldType == Type.FLOAT && rightType == Type.INT) { - - } else { + if(!(oldType == rightType|| oldType == Type.FLOAT && rightType == Type.INT)) { errorHandler("Tried to asssign Type:" + rightType + " to the variable:" + identifier + " that has the type:" + oldType + " And that is hella iligal"); diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java index 8ac12cb..9475fea 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/Semantic_A/TypeCheckerTest.java @@ -231,7 +231,7 @@ void testTypeCheker2() { String correct_error = """ Error 1 - Tried to assign the type:STRING to the array:array that has the type:INT, and that is ilegal + Tried to assign the type:STRING to the array:array that has the type:INT, and that is illegal Error 2 Tried to assign the array:array but acces value: 0 is of type:STRING and should be:Int """; From a2f91b9381ff0738efe4179a82afa2fa54552884 Mon Sep 17 00:00:00 2001 From: Vincent Kosteyev Bechmann Date: Thu, 23 May 2024 16:48:53 +0200 Subject: [PATCH 83/94] Wrote another part of the documentation --- README.md | 2 +- language.md | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++-- model.md | 57 ----------------- 3 files changed, 173 insertions(+), 65 deletions(-) delete mode 100644 model.md diff --git a/README.md b/README.md index eb38796..b59a7af 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ supported, but can be done via the shell (e.g. bash or cmd). Script language --------------- A description of how to write in the language can be found in -[language.md](language.md) +[language.md](language.md). Contact ------- diff --git a/language.md b/language.md index d399dc5..3f06399 100644 --- a/language.md +++ b/language.md @@ -28,14 +28,179 @@ would output: 3 4 -### Types +### Primitive Types CARL has the following primitive types: -| Type | Explanation | Examples | -|-----------|------------------------------------------------------------------------------------------------------------|--------------------------------------| -| `bool` | Boolean value: either `true` or `false`. | `true`, `false` | -| `int` | Integer value: Can be any whole number, either positive or negative (currently limited to 32-bit integers) | `1`, `2`, `32194`, `-900000` | -| `float` | Floating-point value: Can be any real number, with 64-bit precision. | `1.0`, `0.0`, `-10000.0`, `1.404001` | -| `string` | Any text, represented as a string of characters. | "Hello, World!", "123" | +| Type | Explanation | Examples | +|-----------|-------------------------------------------------------------------------------------------------------------------|--------------------------------------| +| `bool` | Boolean value: either `true` or `false`. | `true`, `false` | +| `int` | Integer value: Can be any whole number, either positive or negative (currently limited to signed 32-bit integers) | `1`, `2`, `32194`, `-900000` | +| `float` | Floating-point value: Can be any real number, with 64-bit precision. | `1.0`, `0.0`, `-10000.0`, `1.404001` | +| `string` | Any text, represented as a string of characters. | "Hello, World!", "123" | +On top of this, the language also supports [arrays](#Arrays) and [structs](#Structs). + +### Arrays +CARL supports arrays. Arrays have a static size, can have multiple +dimensions, and require all elements to have the same type. + +A one-dimensional array containing five integers is declared like this: + + var myArray: int[5] + +As stated before, there can be as many dimensions as needed. For +example, to create a three-dimensional array where the dimensions have +sizes of 10, 20, and 30 respectively, the following code is used: + + var threeDimensionalArray: int[10][20][30] + +An array can be of any primitive type, which does not include the +array type or any of the struct types. If an array within an array is +needed, a two-dimensional array can be utilised instead. + +Arrays are zero-indexed, and can be accessed by writing their +identifier, followed by the indices in square brackets. For example, +to print the 4th element of `myArray` (note the zero-indexing): + + print(myArray[3]) + +### Structs + +There are currently four structured data types in CARL: `enemy`, +`floor`, `wall`, and `room`. Each of these structs has a similar construction: + + var : = { + var : = + var : = + ... + } + +#### Enemy +The `enemy` struct is used to represent non-player characters on the +map. It has three properties: `difficulty`, `health`, and `symbol` + +| Name | Type | Explanation | +|--------------|----------|-------------| +| `difficulty` | `int` | ?? | +| `health` | `int` | ?? | +| `symbol` | `string` | ?? | + +The following is an example enemy, an orc: + + var Orc : enemy = { + var difficulty : int = 1 + var health : int = 200 + var symbol : string= "O" + } + +#### Floor + +#### Wall + +#### Room + +## Operators + +CARL supports the following arithmetic operators: + +| Operator | Example | Explanation | +|----------|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| +| `*` | `foo * bar` | Multiplies the two operands. | +| `/` | `foo / bar` | Divides the first operand by the second. | +| `%` | `foo % bar` | Divides the first operand by the second, and returns the remainder from the operation. | +| `+` | `foo + bar` | Adds the two operands. | +| `-` | `foo - bar` | Subtracts the first operand by the second. | +| `..` | `foo..bar` | Returns a random number between the two operands. Will return an integer if both operands are integers, or a float if one of the operands are floats. | + +CARL supports the following relational operators: + +| Operator | Example | Explanation | +|----------|--------------|--------------------------------------------------------------------------| +| `<` | `foo < bar` | Returns `true` if the first operand is less than the second. | +| `<=` | `foo <= bar` | Returns `true` if the first operand is less than or equal to the second. | +| `==` | `foo == bar` | Returns `true` if the first operand is equal to the second. | +| `>=` | `foo >= bar` | Returns `true` if the first operand is more than or equal to the second. | +| `>` | `foo > bar` | Returns `true` if the first operand is more than the second. | +| `!=` | `foo != bar` | Returns `true` if the first operand is not equal to the second. | + +CARL supports the following logical operators: + +| Operator | Example | Explanation | +|----------|---------------|---------------------------------------------------------------------------------------------------------------------------------| +| `!` | `!foo` | Negation operator. If the operand evaluates to `true`, returns `false`, and vice versa. | +| `AND` | `foo AND bar` | Returns `true` if the first operand and the second operand are both `true`. Returns `false` otherwise. | +| `OR` | `foo OR bar` | Returns `true` if either the first operand or the second operand are `true`. Returns `false` only if both operands are `false`. | + +## Control structures +CARL has two main ways to control program flow: if statements, and while +loops. + +### If statements +An if statement allows your program to choose whether to execute one +or more pieces of code, based on one or more conditionals. The +following is the structure of a simple if statement: + + if { + + } + +If `` is true, then `` will execute. Otherwise, the +interpreter will skip `` and simply continue interpretation +after the statement. + +An if statement can also have an else clause, or one or more else-if +clauses. If the first condition is false, the interpreter will go +through each else-if statement's condition, until one of them +evaluates to `true`. If all of them are `false`, the interpreter will +execute the code in the else clause. If there is no else clause, the +interpreter will continue interpretation after the whole structure. +Here is an example of an if statement with several else-if's and +else's: + + if x == 5 { + print("x is five") + } else if x == 10 { + print("x is ten") + } else { + print("x is neither five or ten") + } + +Note that parentheses around the condition are not required. + +### While loops +While loops have a similar structure to if statements: + + while { + + } + +It repeats `` for as long as `` holds. +Here is an example of a while loop, that will print the numbers 1 to 5: + + var i: int = 1 + while i <= 5 { + print(i) + i = i + 1 + } + +## Functions + +### Defining custom functions + +### Builtin functions + + +#### print + +#### generateMap + +#### generateRooms + +#### generateCorridors + +#### generateSpawns + +#### printMap + +#### writeToFile \ No newline at end of file diff --git a/model.md b/model.md deleted file mode 100644 index 738cb24..0000000 --- a/model.md +++ /dev/null @@ -1,57 +0,0 @@ -fn add(a: int, b: int) -> int{ - return a + b; -} - -var x: int = add(1, 2) - -print(x) //Prints to stdout, probably - - -import SimpleRoomGenerator //It is implied that it is builtin - -struct Enemy { - health: int = 0; - enemy_type: type = none; -} - -MAP.grid(width, height); // inbuild function - -MAP.seed = SYSTEM.time().asMillis() //this is the default anyway -//int roomCount, int minRoomSize, int maxRoomSize -map.generateRooms() = simpleRoomGenerate(count, size, size); - - -MAP.put(MAP.rooms[0].centre, PLAYER) // method - -var orc: Enemy// type -orc.health = 50..100 // method - -MAP.put(MAP.centre + (0, 5), orc) // method put in center + 5 hen? - -OUTPUT.format = "json" -OUTPUT.path = "C:\Users\carl\Desktop\output.json" -// WOW, MUCH COMMENT. THIS IS A COMMENT!! WE <3 OUR SUPERVISOR AND MODERATOR - - -if x % 2 == 0 { - noop; -} else { - assassinate former president Bush -} - - -height_map: int[][] = [ - [0, 1, 2, 3], - [4, 5, 6, 7], - [8, 9, 10, 11] -] - -var this_is_random: int = 0..MAP.height - -var playerName: string = "John Jackson" - -var shouldLoop: bool = true -// Potentially implement break and continue -while shouldLoop { - consider assassinating another former president -} \ No newline at end of file From 4b191339b10e4d3b0e8f65d0384b5aeeba7caa18 Mon Sep 17 00:00:00 2001 From: MShadiF Date: Fri, 24 May 2024 11:02:01 +0200 Subject: [PATCH 84/94] Update BinaryOperatorNodeTest.java --- .../carl/CstToAst/BinaryOperatorNodeTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BinaryOperatorNodeTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BinaryOperatorNodeTest.java index 68c2908..e84496d 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BinaryOperatorNodeTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/BinaryOperatorNodeTest.java @@ -35,6 +35,15 @@ public void testGetAstNodeValueFloat() { Assertions.assertEquals("5.0", node.toString()); } + @Test + public void testGetAstNodeValueIntFloat() { + AstNode left = new FloatNode("3.0"); + AstNode right = new IntNode("2"); + AstNode node = BinaryOperatorNode.getAstNodeValue(left, right, "+"); + Assertions.assertEquals("5.0", node.toString()); + Assertions.assertInstanceOf(FloatNode.class, node); + } + @Test public void testGetLeft() { AstNode left = new IntNode("3"); From 31eed885b15a890959a1db30638adb54afc56c93 Mon Sep 17 00:00:00 2001 From: MShadiF Date: Fri, 24 May 2024 12:13:08 +0200 Subject: [PATCH 85/94] Corrected test.carl to args[0] --- src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index 6625b83..7b07465 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -18,7 +18,7 @@ public static void main(String... args) { * Java libary takes in filepath, reads file into memory. Can now be acced * throught identifier fileinput */ - FileInputStream fileInput = new FileInputStream("test.carl"); + FileInputStream fileInput = new FileInputStream(args[0]); // CARLLexer is a generated lexer class for the CARL language. // It tokenizes the input stream (breaks the input into meaningful pieces called // tokens). From 11b3a9f35fc03dda158063355f3c2185de7267c0 Mon Sep 17 00:00:00 2001 From: mantarias <32459446+mantarias@users.noreply.github.com> Date: Mon, 27 May 2024 16:01:26 +0200 Subject: [PATCH 86/94] made the requested additions to struct and builtin functions --- language.md | 62 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/language.md b/language.md index 3f06399..2bc4f21 100644 --- a/language.md +++ b/language.md @@ -29,7 +29,6 @@ would output: 4 ### Primitive Types - CARL has the following primitive types: | Type | Explanation | Examples | @@ -64,9 +63,9 @@ identifier, followed by the indices in square brackets. For example, to print the 4th element of `myArray` (note the zero-indexing): print(myArray[3]) + ### Structs - There are currently four structured data types in CARL: `enemy`, `floor`, `wall`, and `room`. Each of these structs has a similar construction: @@ -75,18 +74,19 @@ There are currently four structured data types in CARL: `enemy`, var : = ... } +property can be any type of variable you want, similar to normal variable declaration works the only one being required in `floor`, `wall`, and `enemy`, is `symbol`. + #### Enemy -The `enemy` struct is used to represent non-player characters on the -map. It has three properties: `difficulty`, `health`, and `symbol` +The `enemy` struct is used to represent non-playable characters on the +map. It has two properties used by other inbuilt functions: `difficulty`, and `symbol`. | Name | Type | Explanation | |--------------|----------|-------------| -| `difficulty` | `int` | ?? | -| `health` | `int` | ?? | -| `symbol` | `string` | ?? | +| `difficulty` | `int` | used by generateSpawns to spawn them is substracted from the given value when put in map | +| `symbol` | `string` | used for symbolizing specific enemy on the map| -The following is an example enemy, an orc: +The following is an example enemy, an orc using custom attributes instead of just relying on inbuilt functions: var Orc : enemy = { var difficulty : int = 1 @@ -95,11 +95,26 @@ The following is an example enemy, an orc: } #### Floor +Floor is used to define a new default floor or a new floor you want to use in custom algorithm. +| Name | Type | Explanation | +|--------------|----------|-------------| +| `symbol` | `string` | used instead of default being f| + #### Wall +Floor is used to define a new default wall or a new wall you want to use in custom algorithm. +| Name | Type | Explanation | +|--------------|----------|-------------| +| `symbol` | `string` | used instead of default being w| -#### Room +#### Room +| Name | Type | Explanation | +|--------------|----------|-------------| +| `x` | `int` | represents starting x point of a room| +| `y` | `int` | represents starting y point of a room| +| `width` | `int` | represents width of a room| +| `height` | `int` | represents height of a room| ## Operators CARL supports the following arithmetic operators: @@ -187,20 +202,41 @@ Here is an example of a while loop, that will print the numbers 1 to 5: ## Functions ### Defining custom functions - +``` + fn test() -> void { + print("test") + } + test() +``` +this would call test function that prints `test` ### Builtin functions - +there exist built-in functions specified below #### print - +`print()` is the basic print function that every langauge has but in the flavour of carl. +To make hello world! string concatenation example using print it would look like this. +``` +print("hello", "world!") +``` +This syntax is the same for variables as well. +``` +var +print("hello", "world!") +``` #### generateMap +`generateMap(20, 20)` this will generate the skeleton of the map by creating a matrix of the size 20X20, and then filling it with the wall tile. It will either take the first wall specified by a `wall` struct and use its symbol or `w` if there is not one. #### generateRooms +`generateRooms(3,5,7)` will place 3 rooms in the map array with size between 5 and 7 tiles. It will either take the first floor specified by a `floor` struct and use its symbol or `f` if there is not one. it will also ccreate room structs for each room with their `x`, `y`., `width`, and `height`. #### generateCorridors +`generateCorridors()` will generate corridors between each room and the next one. #### generateSpawns +`generateSpawns()` will place enemies in a random location in any room besides the last one, to the map array if a difficulty is specified and substracts the difficulty of specific enemies from the specified `int`. During the itterative process of randomly selecting a tile in a random room, it will check if the tile is a floor tile and puts an enemy there. At the end the function will place the player in a random location within the last room, this happens no matter if a parameter is given or not. #### printMap +`printMap()` will print out what the map currently looks like with all the other information like attributes at the bottom. Calling `printMap()` after running `generateMap(20, 20)` it will just print out a 20x20 matrix filled with walls with the default information about wall, floor and player below. -#### writeToFile \ No newline at end of file +#### writeToFile +`writeToFile()` does the exact same thing as `printMap()` but instead of sending it to the standart output it will save to a file called `map.json`. \ No newline at end of file From ebb955b4092035a634930591faf7546636925196 Mon Sep 17 00:00:00 2001 From: Vincent Kosteyev Bechmann Date: Tue, 28 May 2024 01:15:12 +0200 Subject: [PATCH 87/94] Clarity improvements --- language.md | 125 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 38 deletions(-) diff --git a/language.md b/language.md index 2bc4f21..537017f 100644 --- a/language.md +++ b/language.md @@ -38,7 +38,8 @@ CARL has the following primitive types: | `float` | Floating-point value: Can be any real number, with 64-bit precision. | `1.0`, `0.0`, `-10000.0`, `1.404001` | | `string` | Any text, represented as a string of characters. | "Hello, World!", "123" | -On top of this, the language also supports [arrays](#Arrays) and [structs](#Structs). +On top of this, the language also supports [arrays](#Arrays) and +[structs](#Structs). ### Arrays CARL supports arrays. Arrays have a static size, can have multiple @@ -67,26 +68,33 @@ to print the 4th element of `myArray` (note the zero-indexing): ### Structs There are currently four structured data types in CARL: `enemy`, -`floor`, `wall`, and `room`. Each of these structs has a similar construction: +`floor`, `wall`, and `room`. Each of these structs has a similar +construction: var : = { var : = var : = ... } -property can be any type of variable you want, similar to normal variable declaration works the only one being required in `floor`, `wall`, and `enemy`, is `symbol`. +The property can be any variable of any type, but some struct types +may require certain properties (such as `symbol` for `wall`s). + +When a struct is declared, it is added to a list maintained by the +interpreter, and they may be used for builtin functions. #### Enemy The `enemy` struct is used to represent non-playable characters on the -map. It has two properties used by other inbuilt functions: `difficulty`, and `symbol`. +map. It has two properties that are used by builtin functions: +`difficulty`, and `symbol`. | Name | Type | Explanation | |--------------|----------|-------------| -| `difficulty` | `int` | used by generateSpawns to spawn them is substracted from the given value when put in map | -| `symbol` | `string` | used for symbolizing specific enemy on the map| +| `difficulty` | `int` | Used by `generateSpawns()` to spawn them. Is substracted from the given value when put in map | +| `symbol` | `string` | The enemy's symbol on the map | -The following is an example enemy, an orc using custom attributes instead of just relying on inbuilt functions: +The following is an example of an enemy, in this case an orc. It uses +custom attributes, instead of just relying on inbuilt functions: var Orc : enemy = { var difficulty : int = 1 @@ -95,26 +103,30 @@ The following is an example enemy, an orc using custom attributes instead of jus } #### Floor -Floor is used to define a new default floor or a new floor you want to use in custom algorithm. +Floor is used to define a new default floor, or a new floor you want to use a custom algorithm. + | Name | Type | Explanation | |--------------|----------|-------------| -| `symbol` | `string` | used instead of default being f| +| `symbol` | `string` | used instead of default being f | #### Wall -Floor is used to define a new default wall or a new wall you want to use in custom algorithm. +Floor is used to define a new default wall, or a new wall you want to use a custom algorithm. + | Name | Type | Explanation | |--------------|----------|-------------| -| `symbol` | `string` | used instead of default being w| +| `symbol` | `string` | used instead of default being w | #### Room | Name | Type | Explanation | |--------------|----------|-------------| -| `x` | `int` | represents starting x point of a room| -| `y` | `int` | represents starting y point of a room| -| `width` | `int` | represents width of a room| -| `height` | `int` | represents height of a room| +| `x` | `int` | Represents the X coordinate of the room's spawn point | +| `y` | `int` | Represents the Y coordinate of the room's spawn point | +| `width` | `int` | Represents the width of the room | +| `height` | `int` | Represents the height of the room | + + ## Operators CARL supports the following arithmetic operators: @@ -202,41 +214,78 @@ Here is an example of a while loop, that will print the numbers 1 to 5: ## Functions ### Defining custom functions -``` - fn test() -> void { - print("test") +Functions can be defined using the syntax: + + fn () -> { + + } + +The list of parameters is declared like in Rust or Python. An example +can be seen here: + + fn test(firstArg: string) -> void { + print(firstArg) } - test() -``` -this would call test function that prints `test` + test("test") + +This would define a function `test()`, which takes a string as a +parameter. The final line of the example runs the function, which will +print `test` in the console. + ### Builtin functions -there exist built-in functions specified below +As discussed above, CARL does allow the definition of custom +functions, but several functions have been deemed important enough to +be natively supported, and do not need to be defined first. #### print -`print()` is the basic print function that every langauge has but in the flavour of carl. -To make hello world! string concatenation example using print it would look like this. -``` -print("hello", "world!") -``` -This syntax is the same for variables as well. -``` -var -print("hello", "world!") -``` +`print()` is the basic print function that most langauge will have. It +prints the provided arguments to the console. This works both for +literals and for variables. + +If more than one argument is provided, these are printed with +whitespace between them. + +For example, a simple hello world would look like this: + + print("hello", "world!") + + #### generateMap -`generateMap(20, 20)` this will generate the skeleton of the map by creating a matrix of the size 20X20, and then filling it with the wall tile. It will either take the first wall specified by a `wall` struct and use its symbol or `w` if there is not one. +The `generateMap()` function will generate the skeleton of the map, in +the form of a two-dimensional array. It takes two arguments: the width +and height of the map. This skeleton will be filled by the symbol of +the first wall struct in the global struct array, or `w` if there +isn't one. #### generateRooms -`generateRooms(3,5,7)` will place 3 rooms in the map array with size between 5 and 7 tiles. It will either take the first floor specified by a `floor` struct and use its symbol or `f` if there is not one. it will also ccreate room structs for each room with their `x`, `y`., `width`, and `height`. +The `generateRooms()` function will generate rooms in the map, and add +them to the global structs array, with the appropriate values. It +takes three parameters, which refer to: + +1. The amount of rooms to generate +2. The minimum room size +3. The maximum room size + +The room will be filled with the symbol of the first floor struct in +the global struct array, or `f` if there is none. #### generateCorridors -`generateCorridors()` will generate corridors between each room and the next one. +`generateCorridors()` will generate corridors between each room and +the next one. #### generateSpawns -`generateSpawns()` will place enemies in a random location in any room besides the last one, to the map array if a difficulty is specified and substracts the difficulty of specific enemies from the specified `int`. During the itterative process of randomly selecting a tile in a random room, it will check if the tile is a floor tile and puts an enemy there. At the end the function will place the player in a random location within the last room, this happens no matter if a parameter is given or not. +`generateSpawns()` will place enemies on random floor tiles in all +rooms except for the last one, according to the specified difficutly, +and then at the end it will place the player too. #### printMap -`printMap()` will print out what the map currently looks like with all the other information like attributes at the bottom. Calling `printMap()` after running `generateMap(20, 20)` it will just print out a 20x20 matrix filled with walls with the default information about wall, floor and player below. +`printMap()` will print out what the map currently looks like, with +all the other information, like attributes, at the bottom. Calling +`printMap()` after running, for example, `generateMap(20, 20)`, will +print out a 20x20 matrix entirely filled with walls, and then the +default information about the wall, floor and player below. #### writeToFile -`writeToFile()` does the exact same thing as `printMap()` but instead of sending it to the standart output it will save to a file called `map.json`. \ No newline at end of file +`writeToFile()` does the exact same thing as `printMap()`, but instead +of sending it to the standard output, it will save to a file called +`map.json`. From 87527bd156599fc44f4cdc5edd23b53a2a24ab34 Mon Sep 17 00:00:00 2001 From: CarlHejlesen <113053807+CarlHejlesen@users.noreply.github.com> Date: Tue, 28 May 2024 11:11:48 +0200 Subject: [PATCH 88/94] yes --- .../aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java | 2 +- src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java | 9 ++------- test.carl | 5 ++++- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java index 82e56ba..049dc15 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java @@ -182,7 +182,7 @@ public AstNode visitParameterList(CARLParser.ParameterListContext ctx) { List parameters = new ArrayList<>(); if (ctx != null) { for (int i = 0; i < Math.ceilDiv(ctx.getChildCount(), 4); i++) { - System.out.println(ctx.IDENTIFIER().size()); + //System.out.println(ctx.IDENTIFIER().size()); IdentifierNode identifier = new IdentifierNode(ctx.IDENTIFIER(i).getText()); TypeNode type = (TypeNode) visit(ctx.type(i)); parameters.add(new ParameterNode(identifier, type)); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index 7b07465..0f9796b 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -49,18 +49,13 @@ public static void main(String... args) { if (!typeChecker.thereWasAnError) { EvaluatorExecutor inter = new EvaluatorExecutor(); - inter.visit(astRoot); - + inter.visit(astRoot); } // Interpreter is a class that can traverse the AST and interpret or execute the // program based on the AST. } catch (IOException e) { System.out.println(e.toString()); - } catch (Exception e) { - // Catches any exception that occurs within the try block. - // Prints the string representation of the exception to standard output. - System.out.println(); } - } + } } diff --git a/test.carl b/test.carl index fc91ed4..5d66f58 100644 --- a/test.carl +++ b/test.carl @@ -1,10 +1,13 @@ var carl:float = 2 print(carl) +fn carlersej (carlerSupersej:int) -> void{ +} carl =234234 var size : int = 20 var map : float[size][size] -map[2][2] =4.5 \ No newline at end of file +map[2][2] =4.5 + From 02d3f166ae0c539729d4c4edaf49f29403200e57 Mon Sep 17 00:00:00 2001 From: mantarias Date: Tue, 28 May 2024 12:42:16 +0200 Subject: [PATCH 89/94] changed the test files --- test.carl | 15 +++++---------- test3.carl | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 test3.carl diff --git a/test.carl b/test.carl index fc91ed4..8e0a23e 100644 --- a/test.carl +++ b/test.carl @@ -1,10 +1,5 @@ -var carl:float = 2 -print(carl) - -carl =234234 - - -var size : int = 20 -var map : float[size][size] - -map[2][2] =4.5 \ No newline at end of file +generateMap(20,25) +generateRooms(3,5,7) +generateCorridors() +generateSpawns() +writeToFile() \ No newline at end of file diff --git a/test3.carl b/test3.carl new file mode 100644 index 0000000..3962008 --- /dev/null +++ b/test3.carl @@ -0,0 +1,19 @@ +var size : int = 20 +var map : string[size][size] +var i : int = 0 +var j : int = 0 +while i < size{ + j = 0 + while j < size { + map[i][j] = "w" + j = j+1 + } + i = i+1 +} +generateRooms(3,5,7) +generateCorridors() + +var playerX : int = room.get(0).x .. room.get(0).x + room.get(0).width +var playerY : int = room.get(0).y .. room.get(0).y + room.get(0).height +map[playerY][playerX] = "p" +writeToFile() \ No newline at end of file From 38bba256ab880d23504ceadb83eb4a173b7f785f Mon Sep 17 00:00:00 2001 From: Vincent Kosteyev Bechmann Date: Tue, 28 May 2024 12:47:24 +0200 Subject: [PATCH 90/94] Fix not operator --- .../aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java | 7 ++----- .../cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java | 3 +++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java index 82e56ba..1544ddc 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java @@ -316,11 +316,8 @@ public AstNode visitFpNum(CARLParser.FpNumContext ctx) { public AstNode visitNot(CARLParser.NotContext ctx) { AstNode left = visit(ctx.expression()); //Why do we need both a left and a right if they're the same? -Vincent AstNode right = visit(ctx.expression()); - if (left instanceof BoolNode) { - AstNode value = new RelationsAndLogicalOperatorNode(left, right, "!"); - return new BoolNode(value.toString()); - } - return null; + AstNode value = new RelationsAndLogicalOperatorNode(left, right, "!"); + return value; } @Override diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java index f23e7e1..d905c7c 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java @@ -329,6 +329,9 @@ public void visit(VariableDeclarationNode node) { if (node.getValue() instanceof BinaryOperatorNode) { toChange = visit((BinaryOperatorNode) node.getValue()); scopes.getLast().put(node.getIdentifier().toString(), toChange); + } else if (toChange instanceof RelationsAndLogicalOperatorNode) { + toChange = visit((RelationsAndLogicalOperatorNode) node.getValue()); + scopes.getLast().put(node.getIdentifier().toString(), toChange); } else if (toChange instanceof IdentifierNode) { for (HashMap vTable : scopes) { if (vTable.containsKey(toChange.toString())) { From 904d1e1a2e0e5250c64402195bf8fff2633bdd3e Mon Sep 17 00:00:00 2001 From: Vincent Kosteyev Bechmann Date: Tue, 28 May 2024 13:04:44 +0200 Subject: [PATCH 91/94] Tested stuff --- .../carl/SimpleFunctionIntegrationTest.java | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java index 0739341..0ccc5a4 100644 --- a/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java +++ b/src/test/java/dk/aau/cs_24_sw_4_16/carl/SimpleFunctionIntegrationTest.java @@ -767,4 +767,169 @@ public void testingStruct5() throws Exception { assertEquals("1".trim(), outContent.toString().trim()); } + + + @Test + public void testNotTrue() throws Exception { + String code = """ + var x : bool = !true + print(x) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + EvaluatorExecutor interpreter = new EvaluatorExecutor(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("false".trim(), outContent.toString().trim()); + } + + @Test + public void testNotFalse() throws Exception { + String code = """ + var x : bool = !false + print(x) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + EvaluatorExecutor interpreter = new EvaluatorExecutor(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("true".trim(), outContent.toString().trim()); + } + + @Test + public void testNotIdentifiersTrue() throws Exception { + String code = """ + var x : bool = true + var y: !x + print(y) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + EvaluatorExecutor interpreter = new EvaluatorExecutor(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("false".trim(), outContent.toString().trim()); + } + + @Test + public void testNotIdentifiersFalse() throws Exception { + String code = """ + var x : bool = false + var y: !x + print(y) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + EvaluatorExecutor interpreter = new EvaluatorExecutor(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("true".trim(), outContent.toString().trim()); + } + + @Test + public void testNotIdentifiersInIf() throws Exception { + String code = """ + var x : bool = true + + if !x { + print("beep boop") + } + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + EvaluatorExecutor interpreter = new EvaluatorExecutor(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertNotEquals("beep boop".trim(), outContent.toString().trim()); + } + + @Test + public void testNotIdentifiersInIf2() throws Exception { + String code = """ + var x : bool = false + + if !x { + print("beep boop") + } + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + EvaluatorExecutor interpreter = new EvaluatorExecutor(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertEquals("beep boop".trim(), outContent.toString().trim()); + } + + @Test + public void testAMillionNots() throws Exception { + String code = """ + var x : bool = true + var y: !!!!!!!!!!!!!!x + + print(y) + """; + + InputStream stream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8)); + CARLLexer lexer = new CARLLexer(CharStreams.fromStream(stream)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CARLParser parser = new CARLParser(tokens); + ParseTree tree = parser.program(); + CstToAstVisitor visitor = new CstToAstVisitor(); + AstNode astRoot = visitor.visit(tree); + + EvaluatorExecutor interpreter = new EvaluatorExecutor(); + interpreter.visit(astRoot); + + // Assertions can be extended based on the print output or internal state checks + assertNotEquals("true".trim(), outContent.toString().trim()); + } } From bf907c857104d1f2d33467151c32c782f7d5532a Mon Sep 17 00:00:00 2001 From: Deekahy Date: Fri, 21 Jun 2024 13:12:51 +0200 Subject: [PATCH 92/94] test --- .gitignore | 1 + flake.nix | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 flake.nix diff --git a/.gitignore b/.gitignore index 7513c21..20803c6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ target/ .project .factorypath map.json +flake.lock diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..39f544b --- /dev/null +++ b/flake.nix @@ -0,0 +1,17 @@ +{ + inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + + outputs = { self, nixpkgs, }: + let + pkgs = nixpkgs.legacyPackages.x86_64-linux; + in { + devShells.x86_64-linux.default = pkgs.mkShell { + buildInputs = with pkgs; [ + openjdk21 + maven + + ]; + }; + }; +} + From 42b13fd3ef7bf5af728a35de81d96699e1f35553 Mon Sep 17 00:00:00 2001 From: Deekahy Date: Fri, 21 Jun 2024 13:13:54 +0200 Subject: [PATCH 93/94] Revert "Merge pull request #43 from VinceAAU/yes" This reverts commit c353b45868eb86cf83928a5dedb65d18409d6f56, reversing changes made to 4d020a1382ca2811542f306d2f4cffb6965528be. --- .../aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java | 2 +- src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java | 9 +++++++-- test.carl | 3 +-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java index 84a9621..1544ddc 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java @@ -182,7 +182,7 @@ public AstNode visitParameterList(CARLParser.ParameterListContext ctx) { List parameters = new ArrayList<>(); if (ctx != null) { for (int i = 0; i < Math.ceilDiv(ctx.getChildCount(), 4); i++) { - //System.out.println(ctx.IDENTIFIER().size()); + System.out.println(ctx.IDENTIFIER().size()); IdentifierNode identifier = new IdentifierNode(ctx.IDENTIFIER(i).getText()); TypeNode type = (TypeNode) visit(ctx.type(i)); parameters.add(new ParameterNode(identifier, type)); diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java index 0f9796b..7b07465 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Main.java @@ -49,13 +49,18 @@ public static void main(String... args) { if (!typeChecker.thereWasAnError) { EvaluatorExecutor inter = new EvaluatorExecutor(); - inter.visit(astRoot); + inter.visit(astRoot); + } // Interpreter is a class that can traverse the AST and interpret or execute the // program based on the AST. } catch (IOException e) { System.out.println(e.toString()); + } catch (Exception e) { + // Catches any exception that occurs within the try block. + // Prints the string representation of the exception to standard output. + System.out.println(); } - } + } } diff --git a/test.carl b/test.carl index e194f96..8e0a23e 100644 --- a/test.carl +++ b/test.carl @@ -2,5 +2,4 @@ generateMap(20,25) generateRooms(3,5,7) generateCorridors() generateSpawns() -writeToFile() - +writeToFile() \ No newline at end of file From 2dd3ce03a49aa688cab735caea453c225a39ad89 Mon Sep 17 00:00:00 2001 From: Deekahy Date: Fri, 21 Jun 2024 13:14:43 +0200 Subject: [PATCH 94/94] Revert "Fix not operator" This reverts commit 38bba256ab880d23504ceadb83eb4a173b7f785f. --- .../aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java | 7 +++++-- .../cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java | 3 --- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java index 1544ddc..82e56ba 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/CstToAst/CstToAstVisitor.java @@ -316,8 +316,11 @@ public AstNode visitFpNum(CARLParser.FpNumContext ctx) { public AstNode visitNot(CARLParser.NotContext ctx) { AstNode left = visit(ctx.expression()); //Why do we need both a left and a right if they're the same? -Vincent AstNode right = visit(ctx.expression()); - AstNode value = new RelationsAndLogicalOperatorNode(left, right, "!"); - return value; + if (left instanceof BoolNode) { + AstNode value = new RelationsAndLogicalOperatorNode(left, right, "!"); + return new BoolNode(value.toString()); + } + return null; } @Override diff --git a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java index d905c7c..f23e7e1 100644 --- a/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java +++ b/src/main/java/dk/aau/cs_24_sw_4_16/carl/Interpreter/EvaluatorExecutor.java @@ -329,9 +329,6 @@ public void visit(VariableDeclarationNode node) { if (node.getValue() instanceof BinaryOperatorNode) { toChange = visit((BinaryOperatorNode) node.getValue()); scopes.getLast().put(node.getIdentifier().toString(), toChange); - } else if (toChange instanceof RelationsAndLogicalOperatorNode) { - toChange = visit((RelationsAndLogicalOperatorNode) node.getValue()); - scopes.getLast().put(node.getIdentifier().toString(), toChange); } else if (toChange instanceof IdentifierNode) { for (HashMap vTable : scopes) { if (vTable.containsKey(toChange.toString())) {