package de.peeeq.wurstscript.jassIm


abstract syntax:
	
ImProg(
    @ignoreForEquality de.peeeq.wurstscript.ast.Element trace,
    ImVars globals,
	ImFunctions functions,
	ImMethods methods,
	ImClasses classes,
	ImTypeClassFuncs typeClassFunctions,
	java.util.Map<ImVar, java.util.List<ImSet>> globalInits)

ImVars * ImVar
ImFunctions * ImFunction
ImClasses * ImClass
ImTypeClassFuncs * ImTypeClassFunc

ImVar(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImType type, String name, boolean isBJ)

ImType = 
	  ImSimpleType(String typename)
	| ImArrayLikeType
	| ImTupleType(java.util.List<ImType> types, java.util.List<String> names)
	| ImVoid()
	| ImClassType(ref ImClass classDef, ImTypeArguments typeArguments)
	| ImTypeVarRef(ref ImTypeVar typeVariable)
	| ImAnyType()

ImArrayLikeType =
	  ImArrayType(ref ImType entryType)
	| ImArrayTypeMulti(ref ImType entryType, java.util.List<Integer> arraySize)


ImTypeVars * ImTypeVar

ImTypeVar(String name)

ImFunction(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, 
	String name,
	ImTypeVars typeVariables,
	ImVars parameters, 
	ref ImType returnType, 
	ImVars locals, 
	ImStmts body, 
	java.util.List<de.peeeq.wurstscript.translation.imtranslation.FunctionFlag> flags)

ImTypeClassFunc(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace,
	String name,
	ImTypeVars typeVariables,
	ImVars parameters,
	ref ImType returnType)


ImClass(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, 
	String name,
	ImTypeVars typeVariables,
	ImVars fields, 
	ImMethods methods,
	ImFunctions functions,
	java.util.List<ImClassType> superClasses)

ImMethods * ImMethod

ImMethod(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace,
    ref ImClassType methodClass,
	String name,
	ref ImFunction implementation,
	java.util.List<ImMethod> subMethods,
	java.util.List<String> luaMethodDispatchAliases,
	String luaDispatchGroupKey,
	boolean isAbstract)
	
	
ImStmts * ImStmt

ImStmt = 
	  ImIf(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImExpr condition, ImStmts thenBlock, ImStmts elseBlock)
	| ImLoop(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImStmts body)
	| ImExitwhen(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImExpr condition)
	| ImReturn(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImExprOpt returnValue)
	| ImSet(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImLExpr left, ImExpr right)
	| ImExpr
	| ImVarargLoop(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImStmts body, ref ImVar loopVar)
	
	
ImExprOpt =
      ImExpr
    | ImNoExpr()


ImExprs * ImExpr
	
ImExpr = 
	  ImCall
	| ImClassRelatedExpr
	| ImConst
	| ImGetStackTrace()
	| ImCompiletimeExpr(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImExpr expr, int executionOrderIndex)
    | ImLExpr
    | ImTypeVarDispatch(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImTypeClassFunc typeClassFunc, ImExprs arguments
                       , ref ImTypeVar typeVariable)
	| ImCast(ImExpr expr, ref ImType toType)

// an expression which can be used on the left hand side of an assignment
ImLExpr =
      ImVarAccess(ref ImVar var)
    | ImVarArrayAccess(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImVar var, ImExprs indexes)
    | ImTupleSelection(ImExpr tupleExpr, int tupleIndex) // can only be used as L-value if tupleExpr is l-exprs
    | ImMemberAccess
    | ImTupleExpr(ImExprs exprs)                        // can only be used as L-value if exprs only contains l-exprs
    | ImStatementExpr(ImStmts statements, ImExpr expr)  // can only be used as L-value if expr only contains l-exprs



ImClassRelatedExpr =
      ImMemberOrMethodAccess
	| ImClassRelatedExprWithClass

ImMemberOrMethodAccess =
	  ImMethodCall(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImMethod method, ImTypeArguments typeArguments, ImExpr receiver, ImExprs arguments, boolean tuplesEliminated)
	| ImMemberAccess(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImExpr receiver, ImTypeArguments typeArguments, ref ImVar var, ImExprs indexes)

ImClassRelatedExprWithClass =
	  ImAlloc(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImClassType clazz)
	| ImDealloc(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImClassType clazz, ImExpr obj)
	| ImInstanceof(ImExpr obj, ref ImClassType clazz)
	| ImTypeIdOfObj(ImExpr obj, ref ImClassType clazz)
	| ImTypeIdOfClass(ref ImClassType clazz)
	



ImCall = 
	  ImFunctionCall(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImFunction func, ImTypeArguments typeArguments, ImExprs arguments
	  				, boolean tuplesEliminated, de.peeeq.wurstscript.translation.imtranslation.CallType callType)
	| ImOperatorCall(de.peeeq.wurstscript.WurstOperator op, ImExprs arguments)
	
ImConst = 
	  ImIntVal(int valI)
	| ImRealVal(String valR)
	| ImStringVal(String valS)
	| ImBoolVal(boolean valB)
	| ImFuncRef(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ref ImFunction func)
	| ImNull(ref ImType type)

ImTypeArguments * ImTypeArgument

ImTypeArgument(ref ImType type, java.util.Map<ImTypeClassFunc, io.vavr.control.Either<ImMethod, ImFunction>> typeClassBinding)

// helper types:


JassImElementWithName = ImVar | ImFunction | ImClass | ImMethod

ImFuncRefOrCall = ImFuncRef | ImFunctionCall

ElementWithTrace = ImVar | ImFunction | ImClass | ImMethod | ImIf | ImLoop | ImExitwhen | ImReturn
 | ImSet
 | ImMethodCall | ImFunctionCall | ImCompiletimeExpr | ImVarArrayAccess | ImMemberAccess
 | ImProg | ImFuncRef
 | ImAlloc | ImDealloc

ElementWithTypes = ImTupleType | ImArrayTypeMulti

ElementWithVar = ImVarAccess | ImVarArrayAccess | ImMemberAccess


ImPrintable = ImStmt | ImFunction | ImProg | ImVar | ImType | ImStmts | ImExprOpt | ImType | ImTypeVar | ImClass

ImVarWrite = ImSet
ImVarRead  = ImVarAccess | ImVarArrayAccess
	
attributes:
	
ImType.defaultValue
	returns de.peeeq.wurstscript.intermediatelang.ILconst
	implemented by de.peeeq.wurstscript.translation.imtojass.DefaultValue.get

ImPrintable.print(java.lang.Appendable sb, int indent)
	returns void
	implemented by de.peeeq.wurstscript.translation.imtranslation.ImPrinter.print

Element.toString()
	returns String
	implemented by de.peeeq.wurstscript.translation.imtranslation.ImPrinter.asString


ImProg.flatten(de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator)
	returns void
	implemented by de.peeeq.wurstscript.translation.imtranslation.Flatten.flattenProg

ImFunction.flatten(de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator)
	returns void
	implemented by de.peeeq.wurstscript.translation.imtranslation.Flatten.flattenFunc
	
ImStmt.flatten(
		de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator, 
		de.peeeq.wurstscript.jassIm.ImFunction f	
	)
	returns de.peeeq.wurstscript.translation.imtranslation.Flatten.Result
	implemented by de.peeeq.wurstscript.translation.imtranslation.Flatten.flatten

ImLExpr.flattenL(
       		de.peeeq.wurstscript.translation.imtranslation.ImTranslator translator,
       		de.peeeq.wurstscript.jassIm.ImFunction f
       	)
       	returns de.peeeq.wurstscript.translation.imtranslation.Flatten.ResultL
       	implemented by de.peeeq.wurstscript.translation.imtranslation.Flatten.flattenL

ImStmt.attrPurity()
	returns de.peeeq.wurstscript.translation.imtranslation.purity.PurityLevel
	implemented by de.peeeq.wurstscript.translation.imtranslation.purity.PurityLevels.calculate

ImOperatorCall.attrNeedsShortCircuitLowering()
    returns boolean
    implemented by de.peeeq.wurstscript.translation.imtranslation.FlattenAttributes.needsShortCircuitLowering

ImStmts.translate(
		java.util.List<de.peeeq.wurstscript.jassAst.JassStatement> stmts,
		de.peeeq.wurstscript.jassAst.JassFunction f,
		de.peeeq.wurstscript.translation.imtojass.ImToJassTranslator translator
		)
		returns void
		implemented by de.peeeq.wurstscript.translation.imtojass.StatementTranslation.translate
	
ImStmt.translate(
		java.util.List<de.peeeq.wurstscript.jassAst.JassStatement> stmts,
		de.peeeq.wurstscript.jassAst.JassFunction f,
		de.peeeq.wurstscript.translation.imtojass.ImToJassTranslator translator
		)
		returns void
		implemented by de.peeeq.wurstscript.translation.imtojass.StatementTranslation.translate

ImExpr.translate(
		de.peeeq.wurstscript.translation.imtojass.ImToJassTranslator translator
		)
		returns de.peeeq.wurstscript.jassAst.JassExpr
		implemented by de.peeeq.wurstscript.translation.imtojass.ExprTranslation.translate

ImConst.equalValue(ImConst other)
	returns boolean
	implemented by de.peeeq.wurstscript.translation.imtojass.Equality.equalValue
	
ImExpr.attrTyp()
	returns ImType
	implemented by de.peeeq.wurstscript.translation.imtojass.ImAttrType.getType

Element.getNearestFunc()
	returns ImFunction
	implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.getNearestFunc
	
ImType.equalsType(ImType other)
	returns boolean
	implemented by de.peeeq.wurstscript.translation.imtojass.TypeEquality.isEqualType 
	
ImType.translateType()
	returns String
	implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.translateType
	
ImVar.isGlobal()
	returns boolean
	implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.isGlobal

ImStmt.translateStmtToLua(java.util.List<de.peeeq.wurstscript.luaAst.LuaStatement> res, 
						de.peeeq.wurstscript.translation.lua.translation.LuaTranslator tr)
	returns void
	implemented by de.peeeq.wurstscript.translation.lua.translation.StmtTranslation.translate


ImExpr.translateToLua(de.peeeq.wurstscript.translation.lua.translation.LuaTranslator tr)
	returns de.peeeq.wurstscript.luaAst.LuaExpr
	implemented by de.peeeq.wurstscript.translation.lua.translation.ExprTranslation.translate

	
ImStmts.runStatements(de.peeeq.wurstscript.intermediatelang.interpreter.ProgramState globalState
		, de.peeeq.wurstscript.intermediatelang.interpreter.LocalState localState)
	returns void
	implemented by de.peeeq.wurstscript.intermediatelang.interpreter.RunStatement.run
	
ImStmt.runStatement(de.peeeq.wurstscript.intermediatelang.interpreter.ProgramState globalState
		, de.peeeq.wurstscript.intermediatelang.interpreter.LocalState localState)
	returns void
	implemented by de.peeeq.wurstscript.intermediatelang.interpreter.RunStatement.run
	
ImExpr.evaluate(de.peeeq.wurstscript.intermediatelang.interpreter.ProgramState globalState
		, de.peeeq.wurstscript.intermediatelang.interpreter.LocalState localState)
	returns de.peeeq.wurstscript.intermediatelang.ILconst
	implemented by de.peeeq.wurstscript.intermediatelang.interpreter.EvaluateExpr.eval

ImLExpr.evaluateLvalue(de.peeeq.wurstscript.intermediatelang.interpreter.ProgramState globalState
		, de.peeeq.wurstscript.intermediatelang.interpreter.LocalState localState)
	returns de.peeeq.wurstscript.intermediatelang.ILaddress
	implemented by de.peeeq.wurstscript.intermediatelang.interpreter.EvaluateExpr.evaluateLvalue



ImCompiletimeExpr.evaluationResult
    returns java.util.concurrent.atomic.AtomicReference<de.peeeq.wurstscript.intermediatelang.ILconst>
    implemented by de.peeeq.wurstscript.intermediatelang.interpreter.EvaluateExpr.compiletimeEvaluationResult


ImFunction.isNative()
	returns boolean
	implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.isNative

ImFunction.isBj()
	returns boolean
	implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.isBj

ImFunction.isExtern()
	returns boolean
	implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.isExtern

ImFunction.isCompiletime()
	returns boolean
	implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.isCompiletime

ImFunction.hasFlag(de.peeeq.wurstscript.translation.imtranslation.FunctionFlag flag)
	returns boolean
	implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.hasFlag

Element.attrTrace()
	returns de.peeeq.wurstscript.ast.Element
	implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.getTrace
	
Element.attrProg()
	returns ImProg
	implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.getProg
	
ImProg.attrVariableUses
	returns de.peeeq.wurstscript.translation.imoptimizer.VariableUses.Uses
	implemented by de.peeeq.wurstscript.translation.imoptimizer.VariableUses.calcVarUses
	
ImVar.attrWrites
	returns java.util.Collection<ImVarWrite>
	implemented by de.peeeq.wurstscript.translation.imoptimizer.VariableUses.getVarWrites
	
	
ImVar.attrReads
	returns java.util.Collection<ImVarRead>
	implemented by de.peeeq.wurstscript.translation.imoptimizer.VariableUses.getVarReads
	
	
ImFunction.calcUsedVariables()
	returns java.util.Set<ImVar>
	implemented by de.peeeq.wurstscript.translation.imtranslation.UsedVariables.calculate

	
ImFunction.calcReadVariables()
	returns java.util.Set<ImVar>
	implemented by de.peeeq.wurstscript.translation.imtranslation.UsedVariables.calculateReadVars
	
ImFunction.calcUsedFunctions()
	returns java.util.Set<ImFunction>
	implemented by de.peeeq.wurstscript.translation.imtranslation.UsedFunctions.calculate
	

ImMethod.attrClass()
	returns ImClass
	implemented by de.peeeq.wurstscript.translation.imtojass.ImAttributes.attrClass
	
ImClass.attrTypeId()
	returns int
	implemented by de.peeeq.wurstscript.translation.imtranslation.TypeId.get
	
ImClass.isSubclassOf(ImClass other)
	returns boolean
	implemented by de.peeeq.wurstscript.translation.imtranslation.TypeId.isSubclass
	
ImProg.attrTypeId
	returns java.util.Map<ImClass, Integer>
	implemented by de.peeeq.wurstscript.translation.imtranslation.TypeId.calculate

ImClass.attrSubclasses
	returns java.util.List<ImClass>
	implemented by de.peeeq.wurstscript.translation.imtranslation.Subclasses.get
	
ImProg.attrSubclasses
	returns com.google.common.collect.Multimap<ImClass, ImClass>
	implemented by de.peeeq.wurstscript.translation.imtranslation.Subclasses.calculate
		
ImLExpr.isUsedAsLValue()
    returns boolean
    implemented by de.peeeq.wurstscript.translation.imtranslation.LValues.isUsedAsLValue
		
