TypedAST[] classDecls = new TypedAST[toGen.size() + toGenDefs.size() + 1];
toGen.entrySet().stream().forEach(entry->classDecls[cdIdx.getAndIncrement()]
= new ValDeclaration(entry.getKey(), DefDeclaration.getMethodType(entry.getValue().second().getArgBindings(), entry.getValue().first()), entry.getValue().second(), unkLoc));
toGenDefs.entrySet().stream().forEach(entry->classDecls[cdIdx.getAndIncrement()]
= new DefDeclaration(entry.getKey(), new Arrow(Unit.getInstance(), Unit.getInstance()), new LinkedList<>(), entry.getValue(), false));
classDecls[cdIdx.getAndIncrement()] = new DefDeclaration("create", new Arrow(Unit.getInstance(),
new UnresolvedType(wyvClassName)),
Arrays.asList(),
new New(new DeclSequence(), unkLoc), true);
ArrayList<TypedAST> pairedObjDecls = new ArrayList<>();
pairedObjDecls.addAll(Arrays.asList(classDecls));
TypedAST pairedObj = new ClassDeclaration(wyvClassName, "", "", new DeclSequence(pairedObjDecls), unkLoc);
Type parseBufferType = Util.javaToWyvType(ParseBuffer.class);
Type javaClassType = Util.javaToWyvType(javaClass);
TypedAST bufGet = new Application(
new Invocation(new Variable(new NameBindingImpl("buf", null), unkLoc), "getSrcString", null, unkLoc),
UnitVal.getInstance(unkLoc),
unkLoc);
ClassType emptyType =
new ClassType(new Reference<>(Environment.getEmptyEnvironment()), new Reference<>(Environment.getEmptyEnvironment()), new LinkedList<>(), "empty");
TypedAST javaObjInit = new Application(new ExternalFunction(new Arrow(emptyType, Util.javaToWyvType(Value.class)), (env,arg)->{
return Util.toWyvObj(arg);
}),
new Application(
new Invocation(new Variable(new NameBindingImpl(wyvClassName, null), unkLoc), "create", null, unkLoc),
UnitVal.getInstance(unkLoc), unkLoc), unkLoc);
TypedAST body = new Application(new ExternalFunction(new Arrow(Util.javaToWyvType(Object.class), Util.javaToWyvType(TypedAST.class)),
(env,arg)-> (Value)Util.toJavaObject(arg,Value.class)),
new Application(new Invocation(new Application(
new Invocation(new Variable(new NameBindingImpl(javaClassName, null), unkLoc), "create", null, unkLoc),
javaObjInit, unkLoc), "parse", null, unkLoc),
new TupleObject(new TypedAST[] {bufGet, new StringConstant("TSL code")}), unkLoc), unkLoc);
DefDeclaration parseDef =
new DefDeclaration("parse",
new Arrow(parseBufferType, Util.javaToWyvType(TypedAST.class)),
Arrays.asList(new NameBindingImpl("buf", parseBufferType)),
body,
false);