From b12c01732860f9727626829e0b25a273de5fe5c7 Mon Sep 17 00:00:00 2001
From: geno <gabriele.genovese2@studio.unibo.it>
Date: Tue, 25 Jun 2024 16:04:07 +0200
Subject: check semantic of defined and undefined variables implemented do not
 check for built-in function works on the example

---
 src/Main.java                         |   2 +-
 src/ast/nodes/AtomNode.java           |  31 +++++----
 src/ast/nodes/ExprNode.java           | 121 ++++++++++++++++++++++++++++------
 src/ast/nodes/RootNode.java           |   8 +--
 src/ast/types/VoidType.java           |   6 ++
 src/semanticanalysis/SymbolTable.java |  17 +++--
 6 files changed, 140 insertions(+), 45 deletions(-)

diff --git a/src/Main.java b/src/Main.java
index 3987bad..bfc21e3 100644
--- a/src/Main.java
+++ b/src/Main.java
@@ -60,7 +60,7 @@ public class Main {
             Node ast = visitor.visit(tree);
             ArrayList<SemanticError> errors = ast.checkSemantics(ST, 0);
             if (errors.size() > 0) {
-                System.out.println("You had: " + errors.size() + " errors:");
+                System.out.println("You had " + errors.size() + " errors:");
                 for (SemanticError e : errors) {
                     System.out.println("\t" + e);
                 }
diff --git a/src/ast/nodes/AtomNode.java b/src/ast/nodes/AtomNode.java
index 7dc38fb..4c9a807 100644
--- a/src/ast/nodes/AtomNode.java
+++ b/src/ast/nodes/AtomNode.java
@@ -1,15 +1,17 @@
 package ast.nodes;
 
+import ast.types.*;
 import java.util.ArrayList;
-
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import semanticanalysis.SemanticError;
 import semanticanalysis.SymbolTable;
-import ast.types.*;
 
 /**
  * Node for the `atom` statement of the grammar.
  */
 public class AtomNode implements Node {
+
     protected String val;
 
     public AtomNode(String val) {
@@ -23,25 +25,28 @@ public class AtomNode implements Node {
     @Override
     public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
         var errors = new ArrayList<SemanticError>();
-        System.out.println(getId() + " " + _nesting + " " + ST.nslookup(getId()));
-        if (!(this.typeCheck() instanceof IntType) && !ST.top_lookup(this.getId())) {
-            System.out.println(!(this.typeCheck() instanceof IntType) + " " + !ST.top_lookup(this.getId()));
+        // System.out.println("[ATOM] id: " + getId() + " ns: " + _nesting + " top_lookup" + ST.top_lookup(this.getId()));
+        if ((this.typeCheck() instanceof AtomType) && !ST.top_lookup(this.getId())) {
+            // System.out.println(!(this.typeCheck() instanceof IntType) + " " + !ST.top_lookup(this.getId()));
             errors.add(new SemanticError("Undefined name `" + this.getId() + "`"));
         }
 
         return errors;
     }
 
-    // FIXME: this type for atom
+    // ENHANCE: return more specific types
     @Override
     public Type typeCheck() {
-        try {
-            Integer.parseInt(this.val);
-            System.out.println(this.val + " is int");
-            return new IntType();
-        } catch (NumberFormatException e) {
-            System.out.println(this.val + " is atom");
-            return new AtomType();
+        // this regex should match every possible atom name written in this format: CHAR (CHAR | DIGIT)*
+        Pattern pattern = Pattern.compile("^[a-zA-Z][a-zA-Z0-9]*$", Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(this.val);
+        boolean matchFound = matcher.find();
+        if (matchFound) {
+            // System.out.println("Match found for " + this.val);
+            return new AtomType(); // could be a variable or a fuction
+        } else {
+            // System.out.println("Match not found for " + this.val);
+            return new VoidType(); // could be any type of data
         }
     }
 
diff --git a/src/ast/nodes/ExprNode.java b/src/ast/nodes/ExprNode.java
index 39f397e..13b6619 100644
--- a/src/ast/nodes/ExprNode.java
+++ b/src/ast/nodes/ExprNode.java
@@ -1,23 +1,96 @@
 package ast.nodes;
 
+import ast.types.*;
 import java.util.ArrayList;
-
+import java.util.Arrays;
 import semanticanalysis.SemanticError;
 import semanticanalysis.SymbolTable;
-import ast.types.*;
 
 /**
  * Node for the `expr` statement of the grammar.
  */
 public class ExprNode implements Node {
-    private Node atom;
+
+    private AtomNode atom;
     private Node compOp;
     private String op;
     private ArrayList<Node> exprs;
     private ArrayList<Node> trailers;
 
+    private static final String[] bif = {"abs",
+        "aiter",
+        "all",
+        "anext",
+        "any",
+        "ascii",
+        "bin",
+        "bool",
+        "breakpoint",
+        "bytearray",
+        "bytes",
+        "callable",
+        "chr",
+        "classmethod",
+        "compile",
+        "complex",
+        "delattr",
+        "dict",
+        "dir",
+        "divmod",
+        "enumerate",
+        "eval",
+        "exec",
+        "filter",
+        "float",
+        "format",
+        "frozenset",
+        "getattr",
+        "globals",
+        "hasattr",
+        "hash",
+        "help",
+        "hex",
+        "id",
+        "input",
+        "int",
+        "isinstance",
+        "issubclass",
+        "iter",
+        "len",
+        "list",
+        "locals",
+        "map",
+        "max",
+        "memoryview",
+        "min",
+        "next",
+        "object",
+        "oct",
+        "open",
+        "ord",
+        "pow",
+        "print",
+        "property",
+        "range",
+        "repr",
+        "reversed",
+        "round",
+        "set",
+        "setattr",
+        "slice",
+        "sorted",
+        "staticmethod",
+        "str",
+        "sum",
+        "super",
+        "tuple",
+        "type",
+        "vars",
+        "zip",
+        "__import__"};
+
     public ExprNode(Node atom, Node compOp, ArrayList<Node> exprs, String op, ArrayList<Node> trailers) {
-        this.atom = atom;
+        this.atom = (AtomNode) atom;
         this.compOp = compOp;
         this.exprs = exprs;
         this.op = op;
@@ -31,20 +104,28 @@ public class ExprNode implements Node {
     @Override
     public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
         ArrayList<SemanticError> errors = new ArrayList<SemanticError>();
-        if (atom != null) {
-            errors.addAll(atom.checkSemantics(ST, _nesting));
-        }
-
-        if (compOp != null) {
-            errors.addAll(compOp.checkSemantics(ST, _nesting));
-        }
-
-        for (var expr : exprs) {
-            errors.addAll(expr.checkSemantics(ST, _nesting));
-        }
-
-        for (var trailer : trailers) {
-            errors.addAll(trailer.checkSemantics(ST, _nesting));
+        if (atom != null && !trailers.isEmpty()) {
+            // function call
+            if (!Arrays.asList(bif).contains(atom.getId())) {
+                errors.addAll(atom.checkSemantics(ST, _nesting));
+            }
+        } else {
+            // butto tutto quello che c'era prima nell'else così non rischio di perdere niente di utile
+            if (atom != null) {
+                errors.addAll(atom.checkSemantics(ST, _nesting));
+            }
+
+            if (compOp != null) {
+                errors.addAll(compOp.checkSemantics(ST, _nesting));
+            }
+
+            for (var expr : exprs) {
+                errors.addAll(expr.checkSemantics(ST, _nesting));
+            } 
+
+            for (var trailer : trailers) {
+                errors.addAll(trailer.checkSemantics(ST, _nesting));
+            } 
         }
 
         return errors;
@@ -81,11 +162,11 @@ public class ExprNode implements Node {
 
         for (var expr : exprs) {
             str += expr.toPrint(prefix);
-        }
+        } 
 
         for (var trailer : trailers) {
             str += trailer.toPrint(prefix);
-        }
+        } 
 
         if (op != null) {
             str += prefix + "Op(" + op + ")\n";
diff --git a/src/ast/nodes/RootNode.java b/src/ast/nodes/RootNode.java
index 4b7e579..45d20db 100644
--- a/src/ast/nodes/RootNode.java
+++ b/src/ast/nodes/RootNode.java
@@ -1,15 +1,15 @@
 package ast.nodes;
 
+import ast.types.*;
 import java.util.ArrayList;
 import java.util.HashMap;
-
 import semanticanalysis.*;
-import ast.types.*;
 
 /**
  * Node for the `root` statement of the grammar.
  */
 public class RootNode implements Node {
+
     // stms and compundStmts are protected because they are reused for a
     // BlockNode
     protected ArrayList<Node> stmts;
@@ -28,11 +28,11 @@ public class RootNode implements Node {
 
         ST.add(HM);
 
-        for (Node stmt : compoundStmts) {
+        for (Node stmt : stmts) {
             errors.addAll(stmt.checkSemantics(ST, _nesting));
         }
 
-        for (Node stmt : stmts) {
+        for (Node stmt : compoundStmts) {
             errors.addAll(stmt.checkSemantics(ST, _nesting));
         }
 
diff --git a/src/ast/types/VoidType.java b/src/ast/types/VoidType.java
index d15933f..8e3f9b2 100644
--- a/src/ast/types/VoidType.java
+++ b/src/ast/types/VoidType.java
@@ -4,7 +4,13 @@ package ast.types;
  * A void type. Voids return nothing.
  */
 public class VoidType extends Type {
+
     public String toPrint(String prefix) {
         return prefix + "Void\n";
     }
+
+    @Override
+    public String toString() {
+        return "Void";
+    }
 }
diff --git a/src/semanticanalysis/SymbolTable.java b/src/semanticanalysis/SymbolTable.java
index 8193d5e..617b48a 100644
--- a/src/semanticanalysis/SymbolTable.java
+++ b/src/semanticanalysis/SymbolTable.java
@@ -126,15 +126,18 @@ public class SymbolTable {
         // We always increment the offset by 1 otherwise we need ad-hoc bytecode
         // operations
         // FIXME: wtf is that?
-        if (type.getClass().equals((new BoolType()).getClass())) {
-            offs = offs + 1;
-        } else if (type.getClass().equals((new IntType()).getClass())) {
-            offs = offs + 1;
-        } else {
-            offs = offs + 1;
-        }
+        // if (type.getClass().equals((new BoolType()).getClass())) {
+        //     offs = offs + 1;
+        // } else if (type.getClass().equals((new IntType()).getClass())) {
+        //     offs = offs + 1;
+        // } else {
+        //     offs = offs + 1;
+        // }
+        offs = offs + 1;
 
         this.offset.add(offs);
+
+        // System.out.println("Insert " + id + " of type " + type.toString() + " with nesting " + String.valueOf(_nesting));
     }
 
     /**
-- 
cgit v1.2.3-18-g5258