/// <summary> /// Adds a dependency to a .NET/CLR library using clr.load, /// then it sets type to the type in the assembly. /// </summary> /// <param name="c"></param> /// <param name="assembly"></param> /// <param name="type"></param> public static void AddClrDependency(Chunk c, string assembly, string type) { AddClrDependency(c, assembly); // Assignment with FunctionCall AssignmentStatement a = new AssignmentStatement(); CallExpr call = new CallExpr(); call.Scope = c.Scope; Variable require = c.Scope.GetVariable("clr"); VariableExpression v = new VariableExpression(); if (require == null) { require = c.Scope.CreateGlobal("clr"); require.IsGlobal = true; } string name = "", varName = ""; if (type.Contains('.')) { name = type.Substring(0, type.LastIndexOf('.')); varName = type.Substring(type.LastIndexOf('.') + 1); } else { name = assembly; varName = type; } v.Var = require; MemberExpr me = new MemberExpr(); me.Base = v; me.Indexer = "."; me.Ident = "getns"; call.Base = me; call.Arguments.Add(new StringExpr(name) { StringType = TokenType.DoubleQuoteString }); a.IsLocal = true; // local import MemberExpr me2 = new MemberExpr(); me2.Base = call; me2.Indexer = "."; me2.Ident = varName; a.Rhs.Add(me2); Variable var = c.Scope.GetVariable(varName); VariableExpression v2 = new VariableExpression(); if (var == null) { var = c.Scope.CreateLocal(varName); } v2.Var = var; a.Lhs.Add(v2); // Insert after the load c.Body.Insert(1, a); }
// clr.load "<assembly>" // ? clr.usingns(<ns>) // local __ns = clr.getns "<type.ns>" // local <type> = __ns.<type.typename> /// <summary> /// Adds a dependency to a .NET/CLR library using clr.load /// </summary> /// <param name="c"></param> /// <param name="assembly"></param> public static void AddClrDependency(Chunk c, string assembly) { // FunctionCall StringCallExpr call = new StringCallExpr(); Variable require = c.Scope.GetVariable("clr"); VariableExpression v = new VariableExpression(); if (require == null) { require = c.Scope.CreateGlobal("clr"); require.IsGlobal = true; } v.Var = require; MemberExpr me = new MemberExpr(); me.Base = v; me.Indexer = "."; me.Ident = "load"; call.Base = me; call.Arguments.Add(new StringExpr(assembly) { StringType = TokenType.DoubleQuoteString }); c.Body.Insert(0, new CallStatement() { Expression = call, Scope = c.Scope }); }
Expression ParseSuffixedExpr(Scope scope, bool onlyDotColon = false) { // base primary expression Expression prim = ParsePrimaryExpr(scope); while (true) { if (reader.IsSymbol('.') || reader.IsSymbol(':')) { string symb = reader.Get().Data; // '.' or ':' // TODO: should we allow keywords? I vote no. if (!reader.Is(TokenType.Ident)) error("<Ident> expected"); Token id = reader.Get(); MemberExpr m = new MemberExpr(); m.Base = prim; m.Indexer = symb; m.Ident = id.Data; prim = m; } else if (!onlyDotColon && reader.ConsumeSymbol('[')) { int pass = 0; const int maxamount = 100; bool wasLastNumeric = false; bool first = true; bool hadComma = false; do { Token tok = reader.Peek(); int col = tok.Column; int line = tok.Line; Expression ex = ParseExpr(scope); //if (!reader.ConsumeSymbol(']')) //error("']' expected"); IndexExpr i = new IndexExpr(); i.Base = prim; i.Index = ex; prim = i; if ((first || wasLastNumeric) && ex is NumberExpr && hadComma == false) { tok = reader.Peek(); bool cma = reader.ConsumeSymbol(','); if (cma && hadComma == false && first == false) error("Unexpected ',' in matrice indexing", tok.Line, tok.Column, tok); //else if (cma == false && hadComma) // ; hadComma = cma; } else { tok = reader.Peek(); bool cma = reader.ConsumeSymbol(','); //if (cma == false) // break; if (cma && hadComma == false) error("Unexpected ',' in matrice indexing", -1, -1, tok); else if (cma == false && ex is NumberExpr == false && wasLastNumeric && hadComma == false) { error("Expected numeric constant in matrice indexing", line, col, tok); } else if (cma == false && hadComma) if (tok.Type == TokenType.Symbol && tok.Data == "]") ; else error("Expected ','", -1, -1, tok); else if (cma == false) { break; } else { hadComma = true; } hadComma = cma; } if (pass++ >= maxamount) error("Maximum index depth reached"); wasLastNumeric = ex is NumberExpr; first = false; } while (!(reader.Peek().Data == "]")); if (!reader.ConsumeSymbol(']')) error("']' expected"); } else if (!onlyDotColon && reader.ConsumeSymbol('(')) { List<Expression> args = new List<Expression>(); while (!reader.ConsumeSymbol(')')) { Expression ex = ParseExpr(scope); args.Add(ex); if (!reader.ConsumeSymbol(',')) { if (reader.ConsumeSymbol(')')) break; else error("')' expected"); break; } } CallExpr c = new CallExpr(); c.Base = prim; c.Arguments = args; prim = c; } else if (!onlyDotColon && (reader.Is(TokenType.SingleQuoteString) || reader.Is(TokenType.DoubleQuoteString) || reader.Is(TokenType.LongString))) { //string call StringCallExpr e = new StringCallExpr(); e.Base = prim; e.Arguments = new List<Expression> { new StringExpr(reader.Peek().Data) { StringType = reader.Peek().Type } }; reader.Get(); prim = e; } else if (!onlyDotColon && reader.IsSymbol('{')) { // table call // Fix for the issue with whole expr being parsed, not just table. // See LuaMinify issue #2 (https://github.com/stravant/LuaMinify/issues/2) //Expression ex = ParseExpr(scope); Expression ex = ParseSimpleExpr(scope); TableCallExpr t = new TableCallExpr(); t.Base = prim; t.Arguments = new List<Expression> { ex }; prim = t; } else break; } return prim; }