diff --git a/.gitignore b/.gitignore index 6fb050f33df6f21162c8152feb2c2b9d7e8bb16b..2454cbee83e0a4cfe59f360058c3e1901a113b69 100644 --- a/.gitignore +++ b/.gitignore @@ -150,4 +150,4 @@ Session.vim ### recolic *.gi - +*.log diff --git a/src/main/java/chocopy/common/analysis/types/ClassValueType.java b/src/main/java/chocopy/common/analysis/types/ClassValueType.java index 6e91683fd9c6780f1a82fc682e43cfc0f48de643..c84550314b5ddadd471f7fbac90979fccb050a23 100644 --- a/src/main/java/chocopy/common/analysis/types/ClassValueType.java +++ b/src/main/java/chocopy/common/analysis/types/ClassValueType.java @@ -1,9 +1,11 @@ package chocopy.common.analysis.types; +import java.util.Map; import java.util.Objects; import chocopy.common.astnodes.ClassType; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; /** Represents the semantic value of a simple class reference. */ @@ -12,6 +14,10 @@ public class ClassValueType extends ValueType { /** The name of the class. */ private final String className; + // recolic; + @JsonIgnore + public Map<String, SymbolType> memberMap = null; + /** A class type for the class named CLASSNAME. */ @JsonCreator public ClassValueType(@JsonProperty String className) { diff --git a/src/main/java/chocopy/common/astnodes/ClassDef.java b/src/main/java/chocopy/common/astnodes/ClassDef.java index dad7e2a4abcb2653da7bf79053d824d682e84095..16884822ffddd850f5c1b0c5e5866d72b3055263 100644 --- a/src/main/java/chocopy/common/astnodes/ClassDef.java +++ b/src/main/java/chocopy/common/astnodes/ClassDef.java @@ -1,8 +1,10 @@ package chocopy.common.astnodes; +import java.util.Map; import java.util.List; import chocopy.common.analysis.NodeAnalyzer; +import chocopy.common.analysis.types.SymbolType; import java_cup.runtime.ComplexSymbolFactory.Location; /** A class definition. */ @@ -15,6 +17,9 @@ public class ClassDef extends Declaration { /** Body of the class. */ public final List<Declaration> declarations; + // Recolic: + public Map<String, SymbolType> memberMap = null; + /** An AST for class * NAME(SUPERCLASS): * DECLARATIONS. diff --git a/src/main/java/chocopy/pa2/DeclarationAnalyzer.java b/src/main/java/chocopy/pa2/DeclarationAnalyzer.java index 12c534b6f08a582ae715628c2e1ac88fd3da3d15..09ab320be57e261ebe676d984ff232ce36379b9b 100644 --- a/src/main/java/chocopy/pa2/DeclarationAnalyzer.java +++ b/src/main/java/chocopy/pa2/DeclarationAnalyzer.java @@ -8,6 +8,10 @@ import chocopy.common.analysis.types.SymbolType; import chocopy.common.analysis.types.ValueType; import chocopy.common.astnodes.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + /** * Analyzes declarations to create a top-level symbol table. * Recolic: This class will ONLY fill the symTable. Every `Program` and `FuncDef` has a sym table. @@ -60,7 +64,22 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<SymbolType> { @Override public SymbolType analyze(ClassDef classDef) { - System.out.println("debug: classdef"); + assert classDef.memberMap == null; + classDef.memberMap = new HashMap<>(); + assert classDef.memberMap != null; + + ClassValueType result_type = new ClassValueType(classDef.name.name); + SymbolTable<SymbolType> symLayer = new SymbolTable<>(sym); + symLayer.put("self", result_type); + sym = symLayer; + + for(Declaration decl : classDef.declarations) { + String name = decl.getIdentifier().name; + SymbolType type = decl.dispatch(this); + classDef.memberMap.put(name, type); + } + + sym = sym.getParent(); return new ClassValueType(classDef.name.name); } @@ -72,9 +91,12 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<SymbolType> { assert funcDef.symTable != null; // may suck if partial-compiling happens... // Func parameter list + List<ValueType> args = new ArrayList<>(); for(TypedVar param : funcDef.params) { String name = param.identifier.name; - sym.put(name, analyze(param)); + ValueType type = ValueType.annotationToValueType(param.type); + sym.put(name, type); + args.add(type); } for(Declaration decl : funcDef.declarations) { @@ -87,7 +109,8 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<SymbolType> { sym = sym.getParent(); if(sym == null) throw new RuntimeException("logic error: sym parent is null while returning.."); - return new FuncType(ValueType.annotationToValueType(funcDef.returnType)); + FuncType funcT = new FuncType(args, ValueType.annotationToValueType(funcDef.returnType)); + return funcT; } @Override diff --git a/src/main/java/chocopy/pa2/TypeChecker.java b/src/main/java/chocopy/pa2/TypeChecker.java index 5b4e4903047ba8215de5f357fc04b760217532f0..08faeb74a2afd82f5481e3da57ef4ac6222b5465 100644 --- a/src/main/java/chocopy/pa2/TypeChecker.java +++ b/src/main/java/chocopy/pa2/TypeChecker.java @@ -2,10 +2,7 @@ package chocopy.pa2; import chocopy.common.analysis.AbstractNodeAnalyzer; import chocopy.common.analysis.SymbolTable; -import chocopy.common.analysis.types.FuncType; -import chocopy.common.analysis.types.ListValueType; -import chocopy.common.analysis.types.SymbolType; -import chocopy.common.analysis.types.ValueType; +import chocopy.common.analysis.types.*; import chocopy.common.astnodes.*; import java.util.*; @@ -247,6 +244,21 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> { } } + @Override + public SymbolType analyze(MemberExpr node) { + ClassValueType objType = (ClassValueType) node.object.dispatch(this); + if(objType == null) { + err(node, ". operator left operand is not object type."); + return NONE_TYPE; + } + SymbolType resultType = objType.memberMap.get(node.member.name); // currently won't work. classDef not analyzed. + if(resultType == null) { + err(node, "undefined identifier " + node.member.name + " as object member."); + return NONE_TYPE; + } + return resultType; + } + @Override public SymbolType analyze(Identifier id) { String varName = id.name;