/// <summary> /// Generate call to a routine and store result into a variable. /// </summary> /// <para>Stack behavior: </para> /// <list type="number"> /// <item><description>create new variable</description></item> /// <item><description>store returned value</description></item> /// <item><description>nothing left on the stack</description></item> /// </list> /// <param name="call">"CALL" AST fragment</param> /// <returns>SLang variable which holds a value returned from a call.</returns> private Variable GenerateVariableFromCall(Call call) { var routine = GenerateCall(call); if (!routine.SignatureReference.ReturnType.IsVoid) { var variable = new BodyVariable(routine.SignatureDefinition.ReturnType); variable.Store(ip); return(variable); } return(new BodyVariable(Context.TypeSystem.Void)); }
/// <summary> /// Generate "VARIABLE" declaration, evaluate its initializer and assign. /// </summary> /// <para>Stack behavior: expects nothing, leaves nothing.</para> /// <param name="declaration">SLang IR variable declaration.</param> private void GenerateVariableDeclaration(VariableDeclaration declaration) { var name = declaration.Name; var varType = new UnitReference(Context, declaration.Type).Resolve(); Variable variable = new BodyVariable(varType, name); // declare in the current scope scopeCurrent.Declare(name, variable); // evaluate initializer var exprType = GenerateExpression(declaration.Initializer); // assign variable.Store(ip); // verify varType.AssertIsAssignableFrom(exprType); }