Skip to content

Commit

Permalink
check semantic of defined and undefined variables implemented
Browse files Browse the repository at this point in the history
do not check for built-in function
works on the example
  • Loading branch information
gabrielegenovese committed Jun 25, 2024
1 parent da554f4 commit b12c017
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 45 deletions.
2 changes: 1 addition & 1 deletion src/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public static void main(String[] args) {
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);
}
Expand Down
31 changes: 18 additions & 13 deletions src/ast/nodes/AtomNode.java
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -23,25 +25,28 @@ public String getId() {
@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
}
}

Expand Down
121 changes: 101 additions & 20 deletions src/ast/nodes/ExprNode.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -31,20 +104,28 @@ public String getId() {
@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;
Expand Down Expand Up @@ -81,11 +162,11 @@ public String toPrint(String prefix) {

for (var expr : exprs) {
str += expr.toPrint(prefix);
}
}

for (var trailer : trailers) {
str += trailer.toPrint(prefix);
}
}

if (op != null) {
str += prefix + "Op(" + op + ")\n";
Expand Down
8 changes: 4 additions & 4 deletions src/ast/nodes/RootNode.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -28,11 +28,11 @@ public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {

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));
}

Expand Down
6 changes: 6 additions & 0 deletions src/ast/types/VoidType.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
* 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";
}
}
17 changes: 10 additions & 7 deletions src/semanticanalysis/SymbolTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,18 @@ public void insert(String id, Type type, int _nesting, String _label) {
// 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));
}

/**
Expand Down

0 comments on commit b12c017

Please sign in to comment.