/// <summary> /// Extract table entries for the Resources entry of a media. /// </summary> /// <param name="expr">Expression, which is found in the chunk.</param> /// <param name="resources">List for all media resources of this ZMedia.</param> private void getMediaResources ( TableConstructorExpr expr, List<MediaResource> resources ) { foreach ( TableConstructorValueExpr entry in expr.EntryList ) { resources.Add ( getMediaResource ( (TableConstructorExpr) entry.Value ) ); } }
/// <summary> /// Extract table entries for this resource entry of resources. /// </summary> /// <param name="expr">Expression, which is found in the chunk.</param> /// <returns>A media resource object with type, filename and directives. </returns> private MediaResource getMediaResource ( TableConstructorExpr expr ) { MediaResource result = new MediaResource (); foreach ( TableConstructorStringKeyExpr entry in expr.EntryList ) { switch ( entry.Key ) { case "Type": result.Type = (MediaFormat) Enum.Parse ( typeof ( MediaFormat ), getExpressionAsString ( entry.Value ), true ); break; case "Filename": result.Filename = getExpressionAsString ( entry.Value ); break; case "Directives": foreach ( StringExpr str in ( (TableConstructorExpr) entry.Value ).EntryList ) result.Directives.Add ( str.Value ); break; } } return result; }
Expression ParseSimpleExpr(Scope scope) { if (reader.Is(TokenType.Number)) return new NumberExpr { Value = reader.Get().Data }; else if (reader.Is(TokenType.DoubleQuoteString) || reader.Is(TokenType.SingleQuoteString) || reader.Is(TokenType.LongString)) { StringExpr s = new StringExpr { Value = reader.Peek().Data, StringType = reader.Peek().Type }; reader.Get(); return s; } else if (reader.ConsumeKeyword("nil")) return new NilExpr(); else if (reader.IsKeyword("false") || reader.IsKeyword("true")) return new BoolExpr { Value = reader.Get().Data == "true" }; else if (reader.ConsumeSymbol("...")) return new VarargExpr(); else if (reader.ConsumeSymbol('{')) { TableConstructorExpr v = new TableConstructorExpr(); while (true) { if (reader.IsSymbol('[')) { // key reader.Get(); // eat '[' Expression key = ParseExpr(scope); if (!reader.ConsumeSymbol(']')) { error("']' expected"); break; } if (!reader.ConsumeSymbol('=')) { error("'=' Expected"); break; } Expression value = ParseExpr(scope); v.EntryList.Add(new TableConstructorKeyExpr { Key = key, Value = value, }); } else if (reader.Is(TokenType.Ident)) { // value or key Token lookahead = reader.Peek(1); if (lookahead.Type == TokenType.Symbol && lookahead.Data == "=") { // we are a key Token key = reader.Get(); if (!reader.ConsumeSymbol('=')) error("'=' Expected"); Expression value = ParseExpr(scope); v.EntryList.Add(new TableConstructorStringKeyExpr { Key = key.Data, Value = value, }); } else { // we are a value Expression val = ParseExpr(scope); v.EntryList.Add(new TableConstructorValueExpr { Value = val }); } } #if !VANILLA_LUA else if (reader.ConsumeKeyword("function")) { if (reader.Peek().Type != TokenType.Ident) error("function name expected"); string name = reader.Get().Data; FunctionStatement fs = ParseFunctionArgsAndBody(scope); fs.IsLocal = false; fs.Name = new StringExpr(name); v.EntryList.Add(new TableConstructorNamedFunctionExpr { Value = fs }); } #endif else if (reader.ConsumeSymbol('}')) break; else { //value Expression value = ParseExpr(scope); v.EntryList.Add(new TableConstructorValueExpr { Value = value }); } if (reader.ConsumeSymbol(';') || reader.ConsumeSymbol(',')) { // I could have used just an empty statement (';') here, instead of { } // but that leaves a warning, which clutters up the output // other than that, all is good } else if (reader.ConsumeSymbol('}')) break; else { error("'}' or table entry Expected"); break; } } return v; } else if (reader.ConsumeKeyword("function")) { AnonymousFunctionExpr func = ParseExprFunctionArgsAndBody(scope); //func.IsLocal = true; return func; } #if !VANILLA_LUA else if (reader.ConsumeSymbol('|')) { // inline function... |<arg list>| -> <expr>, <expr> InlineFunctionExpression func = new InlineFunctionExpression(); func.Scope = new Scope(scope); // arg list List<Variable> arglist = new List<Variable>(); bool isVarArg = false; while (reader.ConsumeSymbol('|') == false) { if (reader.Is(TokenType.Ident)) { Variable arg = new Variable(); arg.Name = reader.Get().Data; func.Scope.AddLocal(arg); arglist.Add(arg); if (!reader.ConsumeSymbol(',')) { if (reader.ConsumeSymbol('|')) { break; } else { error("'|' expected"); break; } } } else if (reader.ConsumeSymbol("...")) { isVarArg = true; if (!reader.ConsumeSymbol('|')) error("'...' must be the last argument of a function"); break; } else { error("Argument name or '...' expected"); break; } } if (!reader.ConsumeSymbol("->")) error("'->' expected"); // body List<Expression> body = new List<Expression> { ParseExpr(func.Scope) }; while (reader.ConsumeSymbol(',')) body.Add(ParseExpr(func.Scope)); // end //nodeFunc.AstType = AstType.Function; func.Arguments = arglist; func.Expressions = body; func.IsVararg = isVarArg; return func; } #endif else return ParseSuffixedExpr(scope); }