Exemplo n.º 1
0
		protected static bool Apply( ref Tflag flags, Opcode code )
		{
			if( code.Kind() == Opkind.Access )
			{
				if( code == Opcode.Internal )
				{
					flags |= Tflag.Internal;
				}
				else
				{
					flags = ((Tflag)(unchecked((byte)code) & 3)) | (flags & (~((Tflag)3)));
				}
				return true;
			}
			if( code.Kind() == Opkind.Scope )
			{
				if( ((code == Opcode.Readonly) && (flags.Scope() == Tflag.Static)) || ((code == Opcode.Static) && (flags.Scope() == Tflag.Readonly)) )
				{
					flags = Tflag.Rostatic | (flags & (~Tflag.Scope));
				}
				else
				{
					flags = ((Tflag)((unchecked((byte)code) & 7) << 4)) | (flags & (~Tflag.Scope));
				}
				return true;
			}
			if( code == Opcode.Partial )
			{
				flags |= Tflag.Partial;
				return true;
			}
			if( code == Opcode.Unsafe )
			{
				flags |= Tflag.Unsafe;
				return true;
			}
			return false;
		}//Apply
Exemplo n.º 2
0
		/// <summary>
		/// prepare top operator (prepare postfix record or expression tree node)
		/// </summary>
		void Parser.IGenerator.Prepare( Opcode op )
		{
			Debug.Assert( (op.Kind() <= Opkind.Prepost) && (op.Kind() >= Opkind.Special) );
			if( op.Binary() )
			{
				goto binary;
			}
			if( op.Ternary() )
			{
				goto ternary;
			}
			if( op.Multi() )
			{
				goto multi;
			}
			Debug.Assert( op.Unary() );
			var start = PopInt();
			Vneed( 1 );
			Vpush( unchecked((byte)op) );
			Vpush( start );
			return;
		binary:
			var rstart = TopInt();
			var lstart = TopInt( rstart );
			Vneed( 5 );
			Vpush( op.Code() );
			Vpush( lstart );
			return;
		ternary:
			var fstart = TopInt();
			var tstart = TopInt( fstart );
			var cstart = TopInt( tstart );
			Vneed( 5 );
			Vpush( op.Code() );
			Vpush( cstart );
			return;
		multi:
			Debug.Assert( (((op == Opcode.Mcall) || (op == Opcode.Mindex)) || (op == Opcode.Array)) || (op == Opcode.Generic) );
			var mstart = TopInt();
			var n = 1;
			if( (op == Opcode.Mcall) || (op == Opcode.Mindex) )
			{
				n++;
				mstart = TopInt( mstart );
			}
			while( (Parser.OpsAt > 0) && (Parser.Top() == Opcode.Comma) ){
				Parser.Pop();
				n++;
				mstart = TopInt( mstart );
			}
			if( n > 127 )
			{
				throw new ParseError( Parser, "Too many arguments" );
			}
			if( (n == 3) && (op == Opcode.Mcall) )
			{
				Vneed( 5 );
				Vpush( unchecked((byte)Opcode.Call2) );
				Vpush( mstart );
				return;
			}
			Vneed( 6 );
			Vpush( unchecked((byte)n) );
			Vpush( op.Code() );
			Vpush( mstart );
			return;
		}//Parser.IGenerator.Prepare
Exemplo n.º 3
0
		}//Literal
		
		protected override void Special( Opcode op, byte[] code, ref int at )
		{
			var create = false;
		next:
			switch( op )
			{
			case Opcode.Create:
				create = true;
				op = ((Opcode)code[at]).Extend();
				if( (op.Kind() == Opkind.Special) && (unchecked((byte)op) < unchecked((byte)Opcode.Generic)) )
				{
					at++;
					goto next;
				}
				goto case Opcode.Ecall;
			case Opcode.Ecall:
				if( create )
				{
					Typeref( code, ref at );
				}
				else
				{
					Expression( code, ref at );
				}
				Obj self = null;
				if( Value.Type == Vtype.Ident )
				{
					self = Value.Ptr as Obj;
					Value = ((IProps)Value.Ptr).Get( Value.Str );
				}
				var fn = Box( Value );
				Value = create ? new Value( fn.Create( 0 ) ) : fn.Call( self, 0 );
				return;
			case Opcode.Call:
				if( create )
				{
					Typeref( code, ref at );
				}
				else
				{
					Expression( code, ref at );
				}
				self = null;
				if( Value.Type == Vtype.Ident )
				{
					self = Value.Ptr as Obj;
					Value = ((IProps)Value.Ptr).Get( Value.Str );
				}
				fn = Box( Value );
				Expression( code, ref at );
				Args.Add( Result );
				Value = create ? new Value( fn.Create( 1 ) ) : fn.Call( self, 1 );
				Args.Remove( 1 );
				return;
			case Opcode.Call2:
				if( create )
				{
					Typeref( code, ref at );
				}
				else
				{
					Expression( code, ref at );
				}
				self = null;
				if( Value.Type == Vtype.Ident )
				{
					self = Value.Ptr as Obj;
					Value = ((IProps)Value.Ptr).Get( Value.Str );
				}
				fn = Box( Value );
				Expression( code, ref at );
				Args.Add( Result );
				Expression( code, ref at );
				Args.Add( Result );
				Value = create ? new Value( fn.Create( 2 ) ) : fn.Call( self, 2 );
				Args.Remove( 2 );
				return;
			case Opcode.Mcall:
				int n = code[at++];
				if( create )
				{
					Typeref( code, ref at );
				}
				else
				{
					Expression( code, ref at );
				}
				self = null;
				if( Value.Type == Vtype.Ident )
				{
					self = Value.Ptr as Obj;
					Value = ((IProps)Value.Ptr).Get( Value.Str );
				}
				fn = Box( Value );
				var argc = n - 1;
				while( (--n) > 0 ){
					Expression( code, ref at );
					Args.Add( Result );
				}
				Value = create ? new Value( fn.Create( argc ) ) : fn.Call( self, argc );
				Args.Remove( argc );
				return;
			case Opcode.Index:
			case Opcode.Mindex:
				n = op == Opcode.Index ? 2 : code[at++];
				Expression( code, ref at );
				self = null;
				if( Value.Type == Vtype.Ident )
				{
					self = Value.Ptr as Obj;
					Value = ((IProps)Value.Ptr).Get( Value.Str );
				}
				fn = Box( Value );
				argc = n - 1;
				while( (--n) > 0 ){
					Expression( code, ref at );
					Args.Add( Result );
				}
				Value = fn.Index( self, argc );
				Args.Remove( argc );
				return;
			case Opcode.Var:
				var ident = Cident( code, ref at );
				Typeref( code, ref at );
				if( Value.Type == Vtype.Undef )
				{
					Expression( code, ref at );
					Ctx.Vars.Set( ident, Value );
					return;
				}
				fn = Box( Value );
				Expression( code, ref at );
				Args.Add( Result );
				Value = fn.Call( null, 1 );
				Args.Remove( 1 );
				Ctx.Vars.Set( ident, Value );
				return;
			case Opcode.Dot:
				Expression( code, ref at );
				fn = Box( Value );
				ident = Cident( code, ref at );
				Value = new Value( fn, ident );
				return;
			case Opcode.Ternary:
				Expression( code, ref at );
				if( Result.Bool )
				{
					at += 4;
					Expression( code, ref at );
					var fsz = Cint( code, ref at );
					at += fsz;
				}
				else
				{
					var tsz = Cint( code, ref at );
					at += tsz;
					at += 4;
					Expression( code, ref at );
				}
				return;
			}
			throw new NotImplementedException();
		}//Special
Exemplo n.º 4
0
		protected override void Statement( Opcode op, byte[] code, ref int at )
		{
			Debug.Assert( (op.Kind() == Opkind.Statement) || (op.Kind() == Opkind.Statement2) );
			switch( op )
			{
			default:
				throw new NotImplementedException();
			case Opcode.Block:
				if( (Opts & Opt.BlockScope) != 0 )
				{
					Ctx.Push( this );
				}
				Block( code, ref at );
				if( (Opts & Opt.BlockScope) != 0 )
				{
					Ctx.Pop();
				}
				return;
			case Opcode.Return:
			case Opcode.Raise:
				Expression( code, ref at );
				goto case Opcode.Break;
			case Opcode.Break:
			case Opcode.Continue:
				Exit = op;
				return;
			case Opcode.For:
				if( (Opts & Opt.BlockScope) != 0 )
				{
					Ctx.Push( this );
				}
				Expression( code, ref at );
				var test = at;
				var notest = code[at] == 0;
				if( notest )
				{
					++at;
				}
				else
				{
					Expression( code, ref at );
				}
				var size = Cint( code, ref at );
				var last = at;
				var stts = at + size;
				var cend = (stts + 4) + Bits.Int( code, stts );
				if( (Value.Type != Vtype.Undef) && (!Value.Bool) )
				{
					at = cend;
					if( (Opts & Opt.BlockScope) != 0 )
					{
						Ctx.Pop();
					}
					return;
				}
				for( ; ;  )
				{
					at = stts;
					Block( code, ref at );
					if( (Exit != 0) && (Exit != Opcode.Continue) )
					{
						break;
					}
					at = last;
					Expression( code, ref at );
					if( !notest )
					{
						at = test;
						Expression( code, ref at );
						if( !Value.Bool )
						{
							break;
						}
					}
				}
				at = cend;
				if( (Opts & Opt.BlockScope) != 0 )
				{
					Ctx.Pop();
				}
				if( (Exit == Opcode.Break) || (Exit == Opcode.Continue) )
				{
					Exit = 0;
				}
				return;
			case Opcode.While:
			case Opcode.Until:
				if( (Opts & Opt.BlockScope) != 0 )
				{
					Ctx.Push( this );
				}
				test = at;
				do
				{
					at = test;
					Expression( code, ref at );
					if( Value.Bool == (op == Opcode.Until) )
					{
						break;
					}
					Block( code, ref at );
				}
				while( (Exit == 0) || (Exit == Opcode.Continue) );
				if( (Opts & Opt.BlockScope) != 0 )
				{
					Ctx.Pop();
				}
				if( (Exit == Opcode.Break) || (Exit == Opcode.Continue) )
				{
					Exit = 0;
				}
				return;
			case Opcode.Do:
			case Opcode.Dountil:
				if( (Opts & Opt.BlockScope) != 0 )
				{
					Ctx.Push( this );
				}
				do
				{
					Block( code, ref at );
					if( (Exit != 0) && (Exit != Opcode.Continue) )
					{
						break;
					}
					Expression( code, ref at );
				}
				while( Value.Bool != (op == Opcode.Dountil) );
				if( (Opts & Opt.BlockScope) != 0 )
				{
					Ctx.Pop();
				}
				if( (Exit == Opcode.Break) || (Exit == Opcode.Continue) )
				{
					Exit = 0;
				}
				return;
			case Opcode.If:
				if( (Opts & Opt.BlockScope) != 0 )
				{
					Ctx.Push( this );
				}
				Expression( code, ref at );
				if( Value.Bool )
				{
					Block( code, ref at );
					if( (at < code.Length) && (code[at] == unchecked((byte)Opcode.Else)) )
					{
						at++;
						size = Cint( code, ref at );
						at += size;
					}
				}
				else
				{
					size = Cint( code, ref at );
					at += size;
					if( (at < code.Length) && (code[at] == unchecked((byte)Opcode.Else)) )
					{
						at++;
						Block( code, ref at );
					}
				}
				if( (Opts & Opt.BlockScope) != 0 )
				{
					Ctx.Pop();
				}
				return;
			}
		}//Statement
Exemplo n.º 5
0
		}//Unary
		
		protected override void Special( Opcode op, byte[] code, ref int at )
		{
			var paren = Parens;
			var create = false;
		next:
			switch( op )
			{
			case Opcode.Create:
				create = true;
				Write( "new " );
				op = ((Opcode)code[at]).Extend();
				if( (op.Kind() == Opkind.Special) && (unchecked((byte)op) < unchecked((byte)Opcode.Generic)) )
				{
					at++;
					goto next;
				}
				goto case Opcode.Ecall;
			case Opcode.Ecall:
				if( create )
				{
					if( code[at] == unchecked((byte)Opcode.Array) )
					{
						Typeref( code, ref at );
						return;
					}
					Typeref( code, ref at );
				}
				else
				{
					Expression( code, ref at );
				}
				Write( "()" );
				return;
			case Opcode.Call:
				if( create )
				{
					Typeref( code, ref at );
				}
				else
				{
					Expression( code, ref at );
				}
				Write( paren ? '(' : ' ' );
				Expression( code, ref at );
				if( paren )
				{
					Write( ')' );
				}
				return;
			case Opcode.Call2:
				if( create )
				{
					Typeref( code, ref at );
				}
				else
				{
					Expression( code, ref at );
				}
				Write( paren ? '(' : ' ' );
				Expression( code, ref at );
				Write( ", " );
				Expression( code, ref at );
				if( paren )
				{
					Write( ')' );
				}
				return;
			case Opcode.Mcall:
				var mcn = ((int)(code[at++] - 1));
				if( mcn < 2 )
				{
					throw new InvalidOperationException();
				}
				if( create )
				{
					Typeref( code, ref at );
				}
				else
				{
					Expression( code, ref at );
				}
				Write( paren ? '(' : ' ' );
				Expression( code, ref at );
				while( (--mcn) > 0 ){
					Write( ", " );
					Expression( code, ref at );
				}
				if( paren )
				{
					Write( ')' );
				}
				return;
			case Opcode.Index:
				Expression( code, ref at );
				Write( '[' );
				Current = 0;
				Expression( code, ref at );
				Current = op;
				Write( ']' );
				return;
			case Opcode.Mindex:
				mcn = ((int)(code[at++] - 1));
				if( mcn < 2 )
				{
					throw new InvalidOperationException();
				}
				Expression( code, ref at );
				Write( '[' );
				Expression( code, ref at );
				while( (--mcn) > 0 ){
					Write( ", " );
					Expression( code, ref at );
				}
				Write( ']' );
				return;
			case Opcode.Var:
				var n = code[at++];
				var s = Encoding.UTF8.GetString( code, at, n );
				at += n;
				Write( "var " );
				Write( s );
				if( code[at] == 0 )
				{
					at++;
				}
				else
				{
					Write( ' ' );
					Typeref( code, ref at );
				}
				if( code[at] == 0 )
				{
					at++;
				}
				else
				{
					Write( " = " );
					Expression( code, ref at );
				}
				return;
			case Opcode.Dot:
				Expression( code, ref at );
				Write( '.' );
				n = code[at++];
				Write( Encoding.UTF8.GetString( code, at, n ) );
				at += n;
				return;
			case Opcode.Ternary:
				if( paren )
				{
					Write( '(' );
				}
				Expression( code, ref at );
				Write( " ? " );
				at += 4;
				Current = 0;
				Expression( code, ref at );
				Write( " : " );
				at += 4;
				Expression( code, ref at );
				Current = op;
				if( paren )
				{
					Write( ')' );
				}
				return;
			}
			throw new NotImplementedException();
		}//Special
Exemplo n.º 6
0
		}//Nibble
		
		/// <summary>
		/// rewrite literal from parsed value buffer/stack to code buffer
		/// </summary>
		protected override void Literal( Opcode op, int top, int start )
		{
			if( op == Opcode.Ident )
			{
				Copy( op, true, top, start );
				return;
			}
			if( (op < Opcode.Ident) || (op == Opcode.Exception) )
			{
				Write( unchecked((byte)op) );
				return;
			}
			var len = top - start;
			if( (op.Kind() <= Opkind.Number) && (unchecked((byte)op) >= unchecked((byte)Opcode.Char)) )
			{
				Debug.Assert( op <= Opcode.Double );
				Debug.Assert( len == op.Numsz() );
				Need( len + 1 );
				Code[CodeAt++] = unchecked((byte)op);
				Array.Copy( Vals, start, Code, CodeAt, len );
				CodeAt += len;
				return;
			}
			Debug.Assert( op == Opcode.String );
			if( len < (1 << 7) )
			{
				Copy( op, true, top, start );
				return;
			}
			if( len < (1 << 14) )
			{
				Need( 3 + len );
				Code[CodeAt++] = unchecked((byte)op);
				Code[CodeAt++] = unchecked((byte)(0x80 | len));
				Code[CodeAt++] = unchecked((byte)(len >> 7));
				Array.Copy( Vals, start, Code, CodeAt, len );
				CodeAt += len;
				return;
			}
			if( len < (1 << 21) )
			{
				Need( 4 + len );
				Code[CodeAt++] = unchecked((byte)op);
				Code[CodeAt++] = unchecked((byte)(0x80 | len));
				Code[CodeAt++] = unchecked((byte)(0x80 | (len >> 7)));
				Code[CodeAt++] = unchecked((byte)(len >> 14));
				Array.Copy( Vals, start, Code, CodeAt, len );
				CodeAt += len;
				return;
			}
			if( len < (1 << 28) )
			{
				Need( 5 + len );
				Code[CodeAt++] = unchecked((byte)op);
				Code[CodeAt++] = unchecked((byte)(0x80 | len));
				Code[CodeAt++] = unchecked((byte)(0x80 | (len >> 7)));
				Code[CodeAt++] = unchecked((byte)(0x80 | (len >> 14)));
				Code[CodeAt++] = unchecked((byte)(len >> 21));
				Array.Copy( Vals, start, Code, CodeAt, len );
				CodeAt += len;
				return;
			}
			throw new InvalidOperationException();
		}//Literal
Exemplo n.º 7
0
		}//Literal
		
		protected override void Special( Opcode op, byte[] code, ref int at )
		{
			var create = false;
		next:
			switch( op )
			{
			default:
				base.Special( op, code, ref at );
				return;
			case Opcode.Create:
				create = true;
				Write( "new " );
				op = ((Opcode)code[at]).Extend();
				if( (op.Kind() == Opkind.Special) && (unchecked((byte)op) < unchecked((byte)Opcode.Generic)) )
				{
					at++;
					goto next;
				}
				goto case Opcode.Ecall;
			case Opcode.Ecall:
				if( create )
				{
					if( code[at] == unchecked((byte)Opcode.Array) )
					{
						Typeref( code, ref at );
						return;
					}
					Typeref( code, ref at );
				}
				else
				{
					Expression( code, ref at );
				}
				Write( "()" );
				return;
			case Opcode.Call:
				if( create )
				{
					Typeref( code, ref at );
				}
				else
				{
					Expression( code, ref at );
				}
				Write( '(' );
				Expression( code, ref at );
				Write( ')' );
				return;
			case Opcode.Call2:
				if( create )
				{
					Typeref( code, ref at );
				}
				else
				{
					Expression( code, ref at );
				}
				Write( '(' );
				Expression( code, ref at );
				Write( ", " );
				Expression( code, ref at );
				Write( ')' );
				return;
			case Opcode.Mcall:
				var mcn = ((int)(code[at++] - 1));
				if( mcn < 2 )
				{
					throw new InvalidOperationException();
				}
				if( create )
				{
					Typeref( code, ref at );
				}
				else
				{
					Expression( code, ref at );
				}
				Write( '(' );
				Expression( code, ref at );
				while( (--mcn) > 0 ){
					Write( ", " );
					Expression( code, ref at );
				}
				Write( ')' );
				return;
			case Opcode.Dot:
				Debug.Assert( Name.Length == 0 );
				Expression( code, ref at );
				var s = Cident( code, ref at );
				if( Name.Length == 0 )
				{
					Write( '.' );
					Write( Unalias( s, true ) );
					return;
				}
				Name.Append( '.' );
				Name.Append( s );
				if( Inside != Opcode.Dot )
				{
					Write( Unalias() );
				}
				return;
			case Opcode.Var:
				s = Cident( code, ref at );
				if( s[0] == '$' )
				{
					s = s.Substring( 1 );
				}
				else if( Aliasing != Alias.None )
				{
					if( Aliasing == Alias.FirstUpper )
					{
						s = System.Char.ToUpper( s[0] ) + s.Substring( 1 );
					}
					else
					{
						AddLocal( s );
					}
				}
				if( code[at] == 0 )
				{
					at++;
					Write( "var " );
					Write( s );
				}
				else
				{
					Typeref( code, ref at );
					Write( ' ' );
					Write( s );
				}
				if( code[at] == 0 )
				{
					at++;
				}
				else
				{
					Write( " = " );
					Expression( code, ref at );
				}
				return;
			}
		}//Special