コード例 #1
0
ファイル: Parser.cs プロジェクト: Jornason/UniLua
		public LHSAssign() {
			Prev = null;
			Exp  = new ExpDesc();
		}
コード例 #2
0
ファイル: Parser.cs プロジェクト: Jornason/UniLua
		// check whether, in an assignment to an upvalue/local variable, the
		// upvalue/local variable is begin used in a previous assignment to a
		// table. If so, save original upvalue/local value in a safe place and
		// use this safe copy in the previous assignment.
		private void CheckConflict( LHSAssign lh, ExpDesc v )
		{
			var fs = CurFunc;

			// eventual position to save local variable
			int extra = fs.FreeReg;
			bool conflict = false;

			// check all previous assignments
			for( ; lh != null; lh = lh.Prev )
			{
				var e = lh.Exp;
				// assign to a table?
				if( e.Kind == ExpKind.VINDEXED )
				{
					// table is the upvalue/local being assigned now?
					if( e.Ind.Vt == v.Kind && e.Ind.T == v.Info )
					{
						conflict = true;
						e.Ind.Vt = ExpKind.VLOCAL;
						e.Ind.T  = extra; // previous assignment will use safe copy
					}
					// index is the local being assigned? (index cannot be upvalue)
					if( v.Kind == ExpKind.VLOCAL && e.Ind.Idx == v.Info )
					{
						conflict = true;
						e.Ind.Idx = extra; // previous assignment will use safe copy
					}
				}
			}
			if( conflict )
			{
				// copy upvalue/local value to a temporary (in position 'extra')
				var op = (v.Kind == ExpKind.VLOCAL) ? OpCode.OP_MOVE : OpCode.OP_GETUPVAL;
				Coder.CodeABC( fs, op, extra, v.Info, 0 );
				Coder.ReserveRegs( fs, 1 );
			}
		}
コード例 #3
0
ファイル: Parser.cs プロジェクト: Jornason/UniLua
		// assignment -> ',' suffixedexp assignment
		private void Assignment( LHSAssign lh, int nvars )
		{
			CheckCondition( ExpKindUtl.VKIsVar( lh.Exp.Kind ), "syntax error" );
			ExpDesc e = new ExpDesc();

			if( TestNext( (int)',' ) )
			{
				var nv = new LHSAssign();
				nv.Prev = lh;
				SuffixedExp( nv.Exp );
				if( nv.Exp.Kind != ExpKind.VINDEXED )
					CheckConflict( lh, nv.Exp );
				CheckLimit( CurFunc, nvars + Lua.NumCSharpCalls,
					LuaLimits.LUAI_MAXCCALLS, "C# levels" );
				Assignment( nv, nvars+1 );
			}
			else
			{
				CheckNext( (int)'=' );

				int nexps = ExpList( e );
				if( nexps != nvars )
				{
					AdjustAssign( nvars, nexps, e );
					if( nexps > nvars )
					{
						// remove extra values
						CurFunc.FreeReg -= (nexps - nvars);
					}
				}
				else
				{
					Coder.SetOneRet( CurFunc, e );
					Coder.StoreVar( CurFunc, lh.Exp, e );
					return;
				}
			}

			// default assignment
			InitExp( e, ExpKind.VNONRELOC, CurFunc.FreeReg-1 );
			Coder.StoreVar( CurFunc, lh.Exp, e );
		}
コード例 #4
0
ファイル: Parser.cs プロジェクト: Jornason/UniLua
		// stat -> func | assignment
		private void ExprStat()
		{
			var v = new LHSAssign();
			SuffixedExp( v.Exp );

			// stat -> assignment ?
			if( Lexer.Token.TokenType == (int)'=' ||
				Lexer.Token.TokenType == (int)',' )
			{
				v.Prev = null;
				Assignment( v, 1 );
			}

			// stat -> func
			else
			{
				if( v.Exp.Kind != ExpKind.VCALL )
					Lexer.SyntaxError("syntax error");

				var pi = CurFunc.GetCode( v.Exp );
				pi.Value = pi.Value.SETARG_C( 1 ); // call statment uses no results
			}
		}