private int GenerateReference(AstReference ast) { if (ast.IsLocal) { // Local case var dst = ReferenceLocal(ast.Identifier); return(dst); } else if (ast.IsGlobal) { // R(A) := G[K(Bx)] var dst = Push(); var name = ast.Identifier; var litIdx = DefineLiteral(new Value(name)); var litIdxCur = Variables[ast.VarIdx].LitIdx; if (litIdxCur < 0) { var var = Variables[ast.VarIdx]; var.LitIdx = litIdx; Variables[ast.VarIdx] = var; } else if (litIdxCur != litIdx) { throw new System.Exception(); } AddABX(OpCode.GETGLOBAL, dst, ast.VarIdx); return(dst); } else if (ast.IsUpValue) { var envIdx = (byte)ast.UpEnvIdx; var varIdx = (byte)ast.UpVarIdx; //if (envIdx > 0) //{ // UpValue case // R(A) := U[B] var dst = Push(); AddAB(OpCode.GETUPVAL, dst, 0); return(dst); //} //else //{ //} } else { throw new System.Exception(); } }
public static bool TryMatchCall(this AstNode node, out AstIndirectCall indirectCallNode, out AstReference referenceNode, out EntityRef entityRef) { if ((indirectCallNode = node as AstIndirectCall) != null && (referenceNode = indirectCallNode.Subject as AstReference) != null) { entityRef = referenceNode.Entity; return true; } else { referenceNode = null; entityRef = null; return false; } }
/// <summary> /// Emits code responsible for changing the variables identity. /// </summary> /// <param name = "target">The target to compile to</param> private void _emitNewDeclareCode(CompilerTarget target) { _ensureValid(); //create command call // unbind(->variable) var unlinkCall = new AstIndirectCall(Position, PCall.Get, new AstReference(Position, EntityRef.Command.Create(Engine.UnbindAlias))); var targetRef = new AstReference(Position, EntityRef.Variable.Local.Create(Id)); unlinkCall.Arguments.Add(targetRef); //Optimize call and emit code var call = (AstExpr) unlinkCall; _OptimizeNode(target, ref call); call.EmitEffectCode(target); }
public static bool TryMatchCall(this AstNode node, out AstReference referenceNode, out EntityRef entityRef) { AstIndirectCall indirectCallNode; return TryMatchCall(node, out indirectCallNode, out referenceNode, out entityRef); }