@Override public void genTopLevel(TopLevelContext tlc) { for (TypedAST ast : exps) { ast.genTopLevel(tlc); if (ast instanceof Declaration) { ((Declaration) ast).addModuleDecl(tlc); } } }
@Override public Type typecheck(Environment env, Optional<Type> expected) { Type lastType = new Unit(); for (TypedAST t : exps) { if (t == null) continue; lastType = t.typecheck(env, (exps.getLast() == t) ? expected : Optional.empty()); if (t instanceof EnvironmentExtender) env = ((EnvironmentExtender) t).extend(env, env); } retType = lastType; return lastType; }
@Override public Value evaluate(EvaluationEnvironment env) { EvaluationEnvironment iEnv = env; Value lastVal = UnitVal.getInstance(this.getLocation()); for (TypedAST exp : this) { if (exp == null) continue; if (exp instanceof EnvironmentExtender) { iEnv = ((EnvironmentExtender) exp).evalDecl(iEnv); } else { lastVal = exp.evaluate(iEnv); } } return lastVal; }
@Override public Value evaluate(EvaluationEnvironment env) { EvaluationEnvironment outerEnv = env.lookupBinding("oev", TSLBlock.OuterEnviromentBinding.class) .map(oeb -> oeb.getStore()) .orElse(EvaluationEnvironment.EMPTY); return exn.evaluate(outerEnv); }
@Override public Type typecheck(Environment env, Optional<Type> expected) { Environment outerEnv = env.lookupBinding("oev", TSLBlock.OuterTypecheckBinding.class) .map(oeb -> oeb.getStore()) .orElse(Environment.getEmptyEnvironment()); Type exnType = exn.typecheck(outerEnv, expected); cached = Optional.of(exnType); return exnType; }
@Override public void codegenToIL(GenerationEnvironment environment, ILWriter writer) { for (TypedAST ast : exps) { if (ast instanceof ValDeclaration) { environment.register(((ValDeclaration) ast).getName(), ast.getType().generateILType()); writer.wrap( e -> new Let( ((ValDeclaration) ast).getName(), ExpressionWriter.generate( iw -> ((ValDeclaration) ast).getDefinition().codegenToIL(environment, iw)), (Expression) e)); } else if (ast instanceof Declaration) { String genName = GenerationEnvironment.generateVariableName(); List<wyvern.target.corewyvernIL.decl.Declaration> generated = DeclarationWriter.generate( writer, iw -> ast.codegenToIL(new GenerationEnvironment(environment, genName), iw)); writer.wrap(e -> new Let(genName, new New(generated, "this", null), (Expression) e)); } else { ast.codegenToIL(environment, writer); } } }
@Override public Value evaluate(EvaluationEnvironment env) { // TaggedInfo.resolveAll(env, this); Type mo = matchingOver.getType(); TaggedInfo matchingOverTag = TaggedInfo.lookupTagByType(mo); // FIXME: if (matchingOver instanceof Variable) { Variable w = (Variable) matchingOver; // ClassType wType = (ClassType) env.lookup(w.getName()).getType(); // System.out.println("wType = " + wType); // System.out.println("looked up = " + TaggedInfo.lookupTagByType(wType)); // System.out.println("but mot = " + matchingOverTag); matchingOverTag = ((Obj) env.lookup(w.getName()) .map(ib -> ib.getValue(env)) .orElseThrow(() -> new RuntimeException("Invalid matching over tag"))) .getTaggedInfo(); } // System.out.println("Evaluating match with matchingOver = " + matchingOver + " its class " + // matchingOver.getClass()); /* Variable v = (Variable) matchingOver; System.out.println("v.getType() = " + v.getType()); System.out.println("v.getName() = " + v.getName()); System.out.println(env); System.out.println(env.lookup(v.getName())); System.out.println("mo = " + mo + " and its class is " + mo.getClass()); System.out.println(env.lookup(v.getName()).getUse()); System.out.println(env.lookup(v.getName()).getValue(env)); TypeType ttmo = (TypeType) mo; System.out.println("ttmo.getName() is declared but not actual type = " + ttmo.getName()); TypeType tttmo = (TypeType) ((MetadataWrapper) v.typecheck(env, Optional.empty())).getInner(); System.out.println("v.type = " + tttmo.getName()); TaggedInfo.dumpall(env); */ // System.out.println("Evaluating match over tag: " + matchingOverTag + " with matchingOver = " // + matchingOver.getType()); if (matchingOver.getType() instanceof ClassType) { ClassType ct = (ClassType) matchingOver.getType(); // System.out.println("hmm = " + this.matchingOver.typecheck(env, Optional.empty())); // System.out.println("ct = " + ct.getName()); } // System.out.println("matchingOverTag (latest) = " + matchingOverTag); int cnt = 0; for (Case c : cases) { cnt++; // String caseTypeName = getTypeName(c.getAST()); // System.out.println("case "+ cnt + " = " + c); Type tt = c.getTaggedTypeMatch(); TaggedInfo caseTag; if (tt instanceof TypeInv) { TypeInv ti = (TypeInv) tt; // System.out.println("Processing TypeInv case: " + ti); // FIXME: In ECOOP2015Artifact, I am trying to tell the difference between winMod.Win and // bigWinMod.Win... Type ttti = ti.getInnerType(); String mbr = ti.getInvName(); if (ttti instanceof UnresolvedType) { Value objVal = env.lookup(((UnresolvedType) ttti).getName()).get().getValue(env); caseTag = ((Obj) objVal) .getIntEnv() .lookupBinding(mbr, HackForArtifactTaggedInfoBinding.class) .map(b -> b.getTaggedInfo()) .orElseThrow(() -> new RuntimeException("Invalid tag invocation")); } else { // tt = ti.resolve(env); TODO: is this valid? caseTag = TaggedInfo.lookupTagByType(tt); // FIXME: } } else { caseTag = TaggedInfo.lookupTagByType(tt); // FIXME: } // System.out.println("case " + cnt + " type = " + tt); // System.out.println("caseTag = " + caseTag); if (caseTag != null && isSubtag(matchingOverTag, caseTag)) { // We've got a match, evaluate this case // System.out.println("MAAAAATTTCH!"); return c.getAST().evaluate(env); } } // No match, evaluate the default case // System.out.println("DEFAULT: " + defaultCase.getAST().evaluate(env)); return defaultCase.getAST().evaluate(env); }
@Override protected Type doTypecheck(Environment env, Optional<Type> expected) { this.resolve(env); Type matchOverType = matchingOver.typecheck(env, expected); // System.out.println("env = " + env); // System.out.println("matchingOver = " + matchingOver); // System.out.println("matchOverType = " + matchOverType); if (!(matchingOver instanceof Variable)) { throw new RuntimeException("Can only match over variable"); } // Variable v = (Variable) matchingOver; // System.out.println("v = " + v); // System.out.println("v.getType()=" + v.getType()); StaticTypeBinding staticBinding = getStaticTypeBinding(matchingOver, env); // System.out.println(staticBinding); /* if (staticBinding == null) { throw new RuntimeException("variable matching over must be statically tagged"); } */ // Variable we're matching must exist and be a tagged type // String typeName = getTypeName(matchOverType); TaggedInfo matchTaggedInfo = TaggedInfo.lookupTagByType(matchOverType); // FIXME: // System.out.println(matchOverType); if (matchTaggedInfo == null) { ToolError.reportError(ErrorMessage.TYPE_NOT_TAGGED, matchingOver, matchOverType.toString()); } // System.out.println(matchTaggedInfo); matchTaggedInfo.resolve(env, this); // System.out.println(matchTaggedInfo); checkNotMultipleDefaults(); checkDefaultLast(); Type returnType = typecheckCases(env, expected); checkAllCasesAreTagged(env); checkAllCasesAreUnique(); checkSubtagsPreceedSupertags(); // ONLY FOR STATICS FIXME: // System.out.println(env); if (staticBinding != null) { NameBinding nb = env.lookup(staticBinding.getTypeName()); if (nb != null) { checkStaticSubtags(TaggedInfo.lookupTagByType(nb.getType())); // matchTaggedInfo checkBoundedAndUnbounded(TaggedInfo.lookupTagByType(nb.getType())); // matchTaggedInfo } } // If we've omitted default, we must included all possible sub-tags if (defaultCase == null) { // first, the variables tag must use comprised-of! // next, the match cases must include all those in the comprises-of list if (true) {} } // If we've included default, we can't have included all subtags for a tag using comprised-of if (defaultCase != null) { // We only care if tag specifies comprises-of if (matchTaggedInfo.hasComprises()) { // all subtags were specified, error if (comprisesSatisfied(matchTaggedInfo)) { // ToolError.reportError(ErrorMessage.DEFAULT_PRESENT, matchingOver); } } } // System.out.println(expected); if (returnType == null) { if (defaultCase != null) { if (!expected.equals(Optional.empty())) { // System.out.println(defaultCase.getAST().getType()); // System.out.println(expected.get()); if (!expected.get().equals(defaultCase.getAST().getType())) { ToolError.reportError(ErrorMessage.MATCH_NO_COMMON_RETURN, this); return null; } } } } return returnType; }