private static PrefixMemberInfo ParseSuffix(Scope scope, LuaLexer code, PrefixMemberInfo info) { // suffix_opt ::= [ suffix ] // suffix ::= { '[' exp ']' | '.' Identifier | args | ':' Identifier args } // args ::= tablector | string | '(' explist ')' while (true) { switch (code.Current.Typ) { case LuaToken.BracketSquareOpen: // Index code.Next(); info.GenerateGet(scope, InvokeResult.Object); if (code.Current.Typ == LuaToken.BracketSquareClose) info.Indices = new Expression[0]; else info.Indices = ParseExpressionList(scope, code).ToArray(); FetchToken(LuaToken.BracketSquareClose, code); break; case LuaToken.Dot: // Property of an class code.Next(); info.GenerateGet(scope, InvokeResult.Object); info.SetMember(FetchToken(LuaToken.Identifier, code), false); break; case LuaToken.BracketOpen: // List of arguments info.GenerateGet(scope, InvokeResult.Object); info.Arguments = ParseArgumentList(scope, code); break; case LuaToken.BracketCurlyOpen: // LuaTable as an argument info.GenerateGet(scope, InvokeResult.Object); info.Arguments = new ArgumentsList(ParseTableConstructor(scope, code)); break; case LuaToken.String: // String as an argument info.GenerateGet(scope, InvokeResult.Object); info.Arguments = new ArgumentsList(Expression.Constant(FetchToken(LuaToken.String, code).Value, typeof(object))); break; case LuaToken.Colon: // Methodenaufruf code.Next(); // Lese den Namen um den Member zu belegen info.GenerateGet(scope, InvokeResult.Object); info.SetMember(FetchToken(LuaToken.Identifier, code), true); // Parse die Parameter switch (code.Current.Typ) { case LuaToken.BracketOpen: // Argumentenliste info.Arguments = ParseArgumentList(scope, code); break; case LuaToken.BracketCurlyOpen: // LuaTable als Argument info.Arguments = new ArgumentsList(ParseTableConstructor(scope, code) ); break; case LuaToken.String: // String als Argument info.Arguments = new ArgumentsList(Expression.Constant(FetchToken(LuaToken.String, code).Value, typeof(string))); break; } break; default: return info; } } }
private static Expression ParseExpressionCast(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap) { // cast ::= cast(type, expr) if (code.Current.Typ == LuaToken.KwCast) { Token tStart = code.Current; lWrap |= true; PrefixMemberInfo prefix = new PrefixMemberInfo(tStart, ParsePrefixCast(scope, code), null, null, null); ParseSuffix(scope, code, prefix); return prefix.GenerateGet(scope, result); } else return ParsePrefix(scope, code).GenerateGet(scope, result); }
private static PrefixMemberInfo ParsePrefix(Scope scope, LuaLexer code) { // prefix ::= Identifier suffix_opt | '(' exp ')' suffix | literal | tablector Token tStart = code.Current; PrefixMemberInfo info; switch (tStart.Typ) { case LuaToken.BracketOpen: // Parse eine Expression { code.Next(); var expr = ConvertObjectExpression(scope.Runtime, tStart, ParseExpression(scope, code, InvokeResult.Object, scope.EmitExpressionDebug)); FetchToken(LuaToken.BracketClose, code); info = new PrefixMemberInfo(tStart, expr, null, null, null); } break; case LuaToken.DotDotDot: case LuaToken.Identifier: case LuaToken.KwForEach: var t = code.Current; if (t.Value == csClr) // clr is a special package, that always exists { code.Next(); info = new PrefixMemberInfo(tStart, Expression.Property(null, Lua.TypeClrPropertyInfo), null, null, null); } else { string sMemberName; if (t.Typ == LuaToken.DotDotDot) sMemberName = csArgList; else if (t.Typ == LuaToken.KwCast) sMemberName = "cast"; else if (t.Typ == LuaToken.KwForEach) sMemberName = "foreach"; else sMemberName = t.Value; var p = scope.LookupExpression(sMemberName); if (t.Typ == LuaToken.DotDotDot && p == null) throw ParseError(t, Properties.Resources.rsParseNoArgList); code.Next(); if (p == null) // No local variable found info = new PrefixMemberInfo(tStart, scope.LookupExpression(csEnv), t.Value, null, null); else info = new PrefixMemberInfo(tStart, p, null, null, null); } break; case LuaToken.KwCast: info = new PrefixMemberInfo(tStart, ParsePrefixCast(scope, code), null, null, null); break; case LuaToken.String: // Literal String info = new PrefixMemberInfo(tStart, Expression.Constant(FetchToken(LuaToken.String, code).Value, typeof(string)), null, null, null); break; case LuaToken.Number: // Literal Zahl info = new PrefixMemberInfo(tStart, ParseNumber(scope.Runtime, FetchToken(LuaToken.Number, code)), null, null, null); break; case LuaToken.KwTrue: // Literal TRUE code.Next(); info = new PrefixMemberInfo(tStart, Expression.Constant(true, typeof(bool)), null, null, null); break; case LuaToken.KwFalse: // Literal FALSE code.Next(); info = new PrefixMemberInfo(tStart, Expression.Constant(false, typeof(bool)), null, null, null); break; case LuaToken.KwNil: // Literal NIL code.Next(); info = new PrefixMemberInfo(tStart, Expression.Constant(null, typeof(object)), null, null, null); break; case LuaToken.BracketCurlyOpen: // tablector info = new PrefixMemberInfo(tStart, ParseTableConstructor(scope, code), null, null, null); break; case LuaToken.KwFunction: // Function definition code.Next(); info = new PrefixMemberInfo(tStart, ParseLamdaDefinition(scope, code, "lambda", false, null), null, null, null); break; default: throw ParseError(code.Current, Properties.Resources.rsParseUnexpectedTokenPrefix); } return ParseSuffix(scope, code, info); }