diff options
| author | bd-912 <bdunahu@colostate.edu> | 2024-03-16 22:06:32 -0600 | 
|---|---|---|
| committer | bd-912 <bdunahu@colostate.edu> | 2024-03-16 22:06:32 -0600 | 
| commit | 6a24c69232901de51f50beab9c3d3b3760dee334 (patch) | |
| tree | 70c71b9ec25d3f6085d71c83e2be3719fe638ae9 /minijava/TypeCheckSimp.java | |
| parent | 5b09fb3697f4b1cc1f2f3781f10e1334ada69c22 (diff) | |
(Nonfunctional) Implemented many type-checking rules
Diffstat (limited to 'minijava/TypeCheckSimp.java')
| -rw-r--r-- | minijava/TypeCheckSimp.java | 683 | 
1 files changed, 683 insertions, 0 deletions
| diff --git a/minijava/TypeCheckSimp.java b/minijava/TypeCheckSimp.java new file mode 100644 index 0000000..01f8b27 --- /dev/null +++ b/minijava/TypeCheckSimp.java @@ -0,0 +1,683 @@ +package minijava; + +import syntaxtree.*; +import visitor.*; +import java.util.*; + +/** + * Provides default methods which visit each node in the tree in depth-first + * order.  Your visitors may extend this class. + */ +public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,String>> { + +    private void print_filter(String message) { +	boolean debug = true; +	if (debug) +	    System.out.println(message); +    } +    // +    // Auto class visitors--probably don't need to be overridden. +    // +    public TypeInstance visit(NodeList n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	int _count=0; +	for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) { +	    e.nextElement().accept(this,argu); +	    _count++; +	} +	return _ret; +    } + +    public TypeInstance visit(NodeListOptional n, HashMap<String,String> argu) { +	if ( n.present() ) { +	    TypeInstance _ret=null; +	    int _count=0; +	    for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) { +		e.nextElement().accept(this,argu); +		_count++; +	    } +	    return _ret; +	} +	else +	    return null; +    } + +    public TypeInstance visit(NodeOptional n, HashMap<String,String> argu) { +	if ( n.present() ) +	    return n.node.accept(this,argu); +	else +	    return null; +    } + +    public TypeInstance visit(NodeSequence n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	int _count=0; +	for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) { +	    e.nextElement().accept(this,argu); +	    _count++; +	} +	return _ret; +    } + +    public TypeInstance visit(NodeToken n, HashMap<String,String> argu) { return null; } + +    // +    // User-generated visitor methods below +    // + +    /** +     * f0 -> MainClass() +     * f1 -> ( TypeDeclaration() )* +     * f2 -> <EOF> +     */ +    public TypeInstance visit(Goal n, HashMap<String,String> argu) { +	TypeInstance ret = n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	return ret; +    } + +    /** +     * f0 -> "class" +     * f1 -> Identifier() +     * f2 -> "{" +     * f3 -> "public" +     * f4 -> "static" +     * f5 -> "void" +     * f6 -> "main" +     * f7 -> "(" +     * f8 -> "String" +     * f9 -> "[" +     * f10 -> "]" +     * f11 -> Identifier() +     * f12 -> ")" +     * f13 -> "{" +     * f14 -> ( VarDeclaration() )* +     * f15 -> ( Statement() )* +     * f16 -> "}" +     * f17 -> "}" +     */ +    public TypeInstance visit(MainClass n, HashMap<String,String> argu) { +	n.f0.accept(this, argu); +	TypeInstance name = n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	n.f4.accept(this, argu); +	n.f5.accept(this, argu); +	n.f6.accept(this, argu); +	n.f7.accept(this, argu); +	n.f8.accept(this, argu); +	n.f9.accept(this, argu); +	n.f10.accept(this, argu); +	TypeInstance args = n.f11.accept(this, argu); +	n.f12.accept(this, argu); +	n.f13.accept(this, argu); +	TypeInstance var_dec = n.f14.accept(this, argu); +	TypeInstance stmt = n.f15.accept(this, argu); +	n.f16.accept(this, argu); +	n.f17.accept(this, argu); +	return stmt; +    } + +    /** +     * f0 -> ClassDeclaration() +     *               | ClassExtendsDeclaration() +     */ +    public TypeInstance visit(TypeDeclaration n, HashMap<String,String> argu) { +	return n.f0.accept(this, argu); +    } + +    /** +     * f0 -> "class" +     * f1 -> Identifier() +     * f2 -> "{" +     * f3 -> ( VarDeclaration() )* +     * f4 -> ( MethodDeclaration() )* +     * f5 -> "}" +     */ +    public TypeInstance visit(ClassDeclaration n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	n.f4.accept(this, argu); +	n.f5.accept(this, argu); +	return _ret; +    } + +    /** +     * f0 -> "class" +     * f1 -> Identifier() +     * f2 -> "extends" +     * f3 -> Identifier() +     * f4 -> "{" +     * f5 -> ( VarDeclaration() )* +     * f6 -> ( MethodDeclaration() )* +     * f7 -> "}" +     */ +    public TypeInstance visit(ClassExtendsDeclaration n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	n.f4.accept(this, argu); +	n.f5.accept(this, argu); +	n.f6.accept(this, argu); +	n.f7.accept(this, argu); +	return _ret; +    } + +    // FIXME +    /** +     * f0 -> Type() +     * f1 -> Identifier() +     * f2 -> ";" +     */ +    public TypeInstance visit(VarDeclaration n, HashMap<String,String> argu) { +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	return new TypeInstance(TypeEnum.CHECK); +    } + +    /** +     * f0 -> "public" +     * f1 -> Type() +     * f2 -> Identifier() +     * f3 -> "(" +     * f4 -> ( FormalParameterList() )? +     * f5 -> ")" +     * f6 -> "{" +     * f7 -> ( VarDeclaration() )* +     * f8 -> ( Statement() )* +     * f9 -> "return" +     * f10 -> Expression() +     * f11 -> ";" +     * f12 -> "}" +     */ +    public TypeInstance visit(MethodDeclaration n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	n.f4.accept(this, argu); +	n.f5.accept(this, argu); +	n.f6.accept(this, argu); +	n.f7.accept(this, argu); +	n.f8.accept(this, argu); +	n.f9.accept(this, argu); +	n.f10.accept(this, argu); +	n.f11.accept(this, argu); +	n.f12.accept(this, argu); +	return _ret; +    } + +    /** +     * f0 -> FormalParameter() +     * f1 -> ( FormalParameterRest() )* +     */ +    public TypeInstance visit(FormalParameterList n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	return _ret; +    } + +    /** +     * f0 -> Type() +     * f1 -> Identifier() +     */ +    public TypeInstance visit(FormalParameter n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	return _ret; +    } + +    /** +     * f0 -> "," +     * f1 -> FormalParameter() +     */ +    public TypeInstance visit(FormalParameterRest n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	return _ret; +    } + +    /** +     * f0 -> ArrayType() +     *               | BooleanType() +     *               | IntegerType() +     *               | Identifier() +     */ +    public TypeInstance visit(Type n, HashMap<String,String> argu) { +	return n.f0.accept(this, argu); +    } + +    /** +     * f0 -> "int" +     * f1 -> "[" +     * f2 -> "]" +     */ +    public TypeInstance visit(ArrayType n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	return new TypeInstance(TypeEnum.int_array); +    } + +    /** +     * f0 -> "boolean" +     */ +    public TypeInstance visit(BooleanType n, HashMap<String,String> argu) { +	return n.f0.accept(this, argu); +    } + +    /** +     * f0 -> "int" +     */ +    public TypeInstance visit(IntegerType n, HashMap<String,String> argu) { +	return n.f0.accept(this, argu); +    } + +    /** +     * f0 -> Block() +     *               | AssignmentStatement() +     *               | ArrayAssignmentStatement() +     *               | IfStatement() +     *               | WhileStatement() +     *               | PrintStatement() +     */ +    public TypeInstance visit(Statement n, HashMap<String,String> argu) { +	return n.f0.accept(this, argu); +    } + +    /** +     * f0 -> "{" +     * f1 -> ( Statement() )* +     * f2 -> "}" +     */ +    public TypeInstance visit(Block n, HashMap<String,String> argu) { +	n.f0.accept(this, argu); +	TypeInstance ret = n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	return ret; +    } + +    /** +     * f0 -> Identifier() +     * f1 -> "=" +     * f2 -> Expression() +     * f3 -> ";" +     */ +    public TypeInstance visit(AssignmentStatement n, HashMap<String,String> argu) { +	TypeInstance lhs = n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	TypeInstance rhs = n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	return (lhs.equal_type(rhs)) ? +	    new TypeInstance(TypeEnum.CHECK) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> Identifier() +     * f1 -> "[" +     * f2 -> Expression() //int +     * f3 -> "]" +     * f4 -> "=" +     * f5 -> Expression() //int +     * f6 -> ";" +     */ +    public TypeInstance visit(ArrayAssignmentStatement n, HashMap<String,String> argu) { +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	TypeInstance index = n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	n.f4.accept(this, argu); +	TypeInstance value = n.f5.accept(this, argu); +	n.f6.accept(this, argu); +	return (index.get_type() == TypeEnum.integer && +		value.get_type() == TypeEnum.integer) ? +	    new TypeInstance(TypeEnum.CHECK) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> "if" +     * f1 -> "(" +     * f2 -> Expression() +     * f3 -> ")" +     * f4 -> Statement() +     * f5 -> "else" +     * f6 -> Statement() +     */ +    public TypeInstance visit(IfStatement n, HashMap<String,String> argu) { +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	TypeInstance expr = n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	TypeInstance stmt1 = n.f4.accept(this, argu); +	n.f5.accept(this, argu); +	TypeInstance stmt2 = n.f6.accept(this, argu); +	return (expr.get_type() == TypeEnum.bool && +		stmt1.get_type() == stmt2.get_type() == TypeEnum.CHECK) ? +	    new TypeInstance(TypeEnum.CHECK) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> "while" +     * f1 -> "(" +     * f2 -> Expression() +     * f3 -> ")" +     * f4 -> Statement() +     */ +    public TypeInstance visit(WhileStatement n, HashMap<String,String> argu) { +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	TypeInstance expr = n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	TypeInstance stmt = n.f4.accept(this, argu); +	return (expr.get_type() == TypeEnum.bool && +		stmt.get_type() == TypeEnum.CHECK) ? +	    new TypeInstance(TypeEnum.CHECK) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> "System.out.println" +     * f1 -> "(" +     * f2 -> Expression() +     * f3 -> ")" +     * f4 -> ";" +     */ +    public TypeInstance visit(PrintStatement n, HashMap<String,String> argu) { +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	TypeInstance ret = n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	n.f4.accept(this, argu); +	return (ret.get_type() == TypeEnum.integer) ? +	    new TypeInstance(TypeEnum.CHECK) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> AndExpression() +     *               | CompareExpression() +     *               | PlusExpression() +     *               | MinusExpression() +     *               | TimesExpression() +     *               | ArrayLookup() +     *               | ArrayLength() +     *               | MessageSend() +     *               | PrimaryExpression() +     */ +    public TypeInstance visit(Expression n, HashMap<String,String> argu) { +	return n.f0.accept(this, argu); +    } + +    /** +     * f0 -> PrimaryExpressionppp() +     * f1 -> "&&" +     * f2 -> PrimaryExpression() +     */ +    public TypeInstance visit(AndExpression n, HashMap<String,String> argu) { +	TypeInstance oper1 = n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	TypeInstance oper2 = n.f2.accept(this, argu); +	return (oper1.get_type() == TypeEnum.bool && +		oper2.get_type() == TypeEnum.bool) ? +	    new TypeInstance(TypeEnum.bool) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> PrimaryExpression() +     * f1 -> "<" +     * f2 -> PrimaryExpression() +     */ +    public TypeInstance visit(CompareExpression n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	TypeInstance oper1 = n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	TypeInstance oper2 = n.f2.accept(this, argu); +	return (oper1.get_type() == TypeEnum.integer && +		oper2.get_type() == TypeEnum.integer) ? +	    new TypeInstance(TypeEnum.bool) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> PrimaryExpression() +     * f1 -> "+" +     * f2 -> PrimaryExpression() +     */ +    public TypeInstance visit(PlusExpression n, HashMap<String,String> argu) { +	TypeInstance oper1 = n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	TypeInstance oper2 = n.f2.accept(this, argu); +	return (oper1.get_type() == TypeEnum.integer && +		oper2.get_type() == TypeEnum.integer) ? +	    new TypeInstance(TypeEnum.integer) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> PrimaryExpression() +     * f1 -> "-" +     * f2 -> PrimaryExpression() +     */ +    public TypeInstance visit(MinusExpression n, HashMap<String,String> argu) { +	TypeInstance oper1 = n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	TypeInstance oper2 = n.f2.accept(this, argu); +	return (oper1.get_type() == TypeEnum.integer && +		oper2.get_type() == TypeEnum.integer) ? +	    new TypeInstance(TypeEnum.integer) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> PrimaryExpression() +     * f1 -> "*" +     * f2 -> PrimaryExpression() +     */ +    public TypeInstance visit(TimesExpression n, HashMap<String,String> argu) { +	TypeInstance oper1 = n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	TypeInstance oper2 = n.f2.accept(this, argu); +	return (oper1.get_type() == TypeEnum.integer && +		oper2.get_type() == TypeEnum.integer) ? +	    new TypeInstance(TypeEnum.integer) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> PrimaryExpression() +     * f1 -> "[" +     * f2 -> PrimaryExpression() +     * f3 -> "]" +     */ +    public TypeInstance visit(ArrayLookup n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	TypeInstance array = n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	TypeInstance index = n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	return (array.get_type() == TypeEnum.int_array && +		index.get_type() == TypeEnum.integer) ? +	    new TypeInstance(TypeEnum.integer) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> PrimaryExpression() +     * f1 -> "." +     * f2 -> "length" +     */ +    public TypeInstance visit(ArrayLength n, HashMap<String,String> argu) { +	// can only act on an array +	TypeInstance _ret=null; +	TypeInstance ret = n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	return (ret.get_type() == TypeEnum.int_array) ? new TypeInstance(TypeEnum.integer) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> PrimaryExpression() +     * f1 -> "." +     * f2 -> Identifier() +     * f3 -> "(" +     * f4 -> ( ExpressionList() )? +     * f5 -> ")" +     */ +    public TypeInstance visit(MessageSend n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	n.f4.accept(this, argu); +	n.f5.accept(this, argu); +	return _ret; +    } + +    // FIXME +    /** +     * f0 -> Expression() +     * f1 -> ( ExpressionRest() )* +     */ +    public TypeInstance visit(ExpressionList n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	n.f0.accept(this, argu); +	n.f1.accept(this, argu); +	return _ret; +    } + +    /** +     * f0 -> "," +     * f1 -> Expression() +     */ +    public TypeInstance visit(ExpressionRest n, HashMap<String,String> argu) { +	n.f0.accept(this, argu); +	TypeInstance ret = n.f1.accept(this, argu); +	return ret; +    } + +    /** +     * f0 -> IntegerLiteral() +     *               | TrueLiteral() +     *               | FalseLiteral() +     *               | Identifier() +     *               | ThisExpression() +     *               | ArrayAllocationExpression() +     *               | AllocationExpression() +     *               | NotExpression() +     *               | BracketExpression() +     */ +    public TypeInstance visit(PrimaryExpression n, HashMap<String,String> argu) { +	return n.f0.accept(this, argu); +    } + +    /** +     * f0 -> <INTEGER_LITERAL> +     */ +    public TypeInstance visit(IntegerLiteral n, HashMap<String,String> argu) { +	return new TypeInstance(TypeEnum.integer); +    } + +    /** +     * f0 -> "true" +     */ +    public TypeInstance visit(TrueLiteral n, HashMap<String,String> argu) { +	return new TypeInstance(TypeEnum.bool); +    } + +    /** +     * f0 -> "false" +     */ +    public TypeInstance visit(FalseLiteral n, HashMap<String,String> argu) { +	return new TypeInstance(TypeEnum.bool); +    } + +    /** +     * f0 -> <IDENTIFIER> +     */ +    public TypeInstance visit(Identifier n, HashMap<String,String> argu) { +	return new TypeInstance(TypeEnum.CHECK); +    } + +    //FIXME +    /** +     * f0 -> "this" +     */ +    public TypeInstance visit(ThisExpression n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	n.f0.accept(this, argu); +	return _ret; +    } + +    /** +     * f0 -> "new" +     * f1 -> "int" +     * f2 -> "[" +     * f3 -> Expression() +     * f4 -> "]" +     */ +    public TypeInstance visit(ArrayAllocationExpression n, HashMap<String,String> argu) { +	TypeInstance _ret=null; +	n.f0.accept(this, argu); +	TypeInstance ret = n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	n.f4.accept(this, argu); +	return (ret.get_type() == TypeEnum.integer) ? new TypeInstance(TypeEnum.int_array) : +	    new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> "new" +     * f1 -> Identifier() +     * f2 -> "(" +     * f3 -> ")" +     */ +    public TypeInstance visit(AllocationExpression n, HashMap<String,String> argu) { +	n.f0.accept(this, argu); +	TypeInstance ret = n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	n.f3.accept(this, argu); +	return ret; +    } + +    /** +     * f0 -> "!" +     * f1 -> Expression() +     */ +    public TypeInstance visit(NotExpression n, HashMap<String,String> argu) { +	n.f0.accept(this, argu); +	TypeInstance ret = n.f1.accept(this, argu); +	return (ret.get_type() == TypeEnum.bool) ? ret : new TypeInstance(TypeEnum.ERROR); +    } + +    /** +     * f0 -> "(" +     * f1 -> Expression() +     * f2 -> ")" +     */ +    public TypeInstance visit(BracketExpression n, HashMap<String,String> argu) { +	n.f0.accept(this, argu); +	TypeInstance ret = n.f1.accept(this, argu); +	n.f2.accept(this, argu); +	return ret; +    } + +} | 
