internal string DoExpr(Expression e) { string ret = null; if (e is AnonymousFunctionExpr) // function() ... end { // TODO: optimize into InlineFunctionExpr? AnonymousFunctionExpr f = e as AnonymousFunctionExpr; StringBuilder sb = new StringBuilder(); sb.Append("function("); for (int i = 0; i < f.Arguments.Count; i++) { sb.Append(f.Arguments[i].Name); if (i != f.Arguments.Count - 1 || f.IsVararg) { sb.Append(","); } } if (f.IsVararg) { sb.Append("..."); } sb.Append(")"); sb.Append(DoChunk(f.Body)); sb.Append(" end"); ret = sb.ToString(); } else if (e is BinOpExpr) { string left = DoExpr((e as BinOpExpr).Lhs); string op = (e as BinOpExpr).Op; string right = DoExpr((e as BinOpExpr).Rhs); ret = string.Format("{0}{1}{2}", left, op, right); } else if (e is BoolExpr) { bool val = (e as BoolExpr).Value; ret = val ? "true" : "false"; } else if (e is CallExpr && (!(e is StringCallExpr) && !(e is TableCallExpr))) { CallExpr c = e as CallExpr; StringBuilder sb = new StringBuilder(); sb.Append(DoExpr(c.Base) + "("); for (int i = 0; i < c.Arguments.Count; i++) { sb.Append(DoExpr(c.Arguments[i])); if (i != c.Arguments.Count - 1) { sb.Append(","); } } sb.Append(")"); ret = sb.ToString(); } else if (e is StringCallExpr) { StringCallExpr s = e as StringCallExpr; ret = string.Format("{0}{1}", DoExpr(s.Base), DoExpr(s.Arguments[0])); } else if (e is TableCallExpr) { TableCallExpr s = e as TableCallExpr; ret = string.Format("{0}{1}", DoExpr(s.Base), DoExpr(s.Arguments[0])); } else if (e is IndexExpr) { IndexExpr i = e as IndexExpr; ret = string.Format("{0}[{1}]", DoExpr(i.Base), DoExpr(i.Index)); } else if (e is InlineFunctionExpression) // |<args>| -> <exprs> { InlineFunctionExpression ife = e as InlineFunctionExpression; StringBuilder sb = new StringBuilder(); sb.Append("|"); for (int i = 0; i < ife.Arguments.Count; i++) { sb.Append(ife.Arguments[i].Name); if (i != ife.Arguments.Count - 1 || ife.IsVararg) { sb.Append(", "); } } if (ife.IsVararg) { sb.Append("..."); } sb.Append("|->"); for (int i2 = 0; i2 < ife.Expressions.Count; i2++) { sb.Append(DoExpr(ife.Expressions[i2])); if (i2 != ife.Expressions.Count - 1) { sb.Append(","); } } ret = sb.ToString(); } else if (e is TableConstructorKeyExpr) { TableConstructorKeyExpr t = e as TableConstructorKeyExpr; ret = "[" + DoExpr(t.Key) + "]=" + DoExpr(t.Value); } else if (e is MemberExpr) { MemberExpr m = e as MemberExpr; ret = DoExpr(m.Base) + m.Indexer + m.Ident; } else if (e is NilExpr) { ret = "nil"; } else if (e is NumberExpr) { ret = (e as NumberExpr).Value; } else if (e is StringExpr) { StringExpr se = e as StringExpr; string delim = se.StringType == TokenType.SingleQuoteString ? "'" : (se.StringType == TokenType.DoubleQuoteString ? "\"" : "["); if (delim == "[") { // Long strings keep their [=*[ ret = se.Value; } else { ret = delim + se.Value + delim; } } else if (e is TableConstructorStringKeyExpr) { TableConstructorStringKeyExpr tcske = e as TableConstructorStringKeyExpr; ret = tcske.Key + "=" + DoExpr(tcske.Value); } else if (e is TableConstructorExpr) { TableConstructorExpr t = e as TableConstructorExpr; StringBuilder sb = new StringBuilder(); sb.Append("{"); for (int i = 0; i < t.EntryList.Count; i++) { sb.Append(DoExpr(t.EntryList[i])); if (i != t.EntryList.Count - 1) { sb.Append(","); } } sb.Append("}"); ret = sb.ToString(); } else if (e is UnOpExpr) { string op = (e as UnOpExpr).Op; string s = op; if (s.Length != 1) { s += " "; } ret = s + DoExpr((e as UnOpExpr).Rhs); } else if (e is TableConstructorValueExpr) { ret = DoExpr((e as TableConstructorValueExpr).Value); } else if (e is VarargExpr) { ret = "..."; } else if (e is VariableExpression) { ret = (e as VariableExpression).Var.Name; } if (ret != null) { return(string.Format("{0}{1}{2}", "(".Repeat(e.ParenCount), ret, ")".Repeat(e.ParenCount))); } throw new NotImplementedException(e.GetType().Name + " is not implemented"); }
internal string DoExpr(Expression e, List <Token> tok, ref int index, Scope s) { int startP = index; for (int i = 0; i < e.ParenCount; i++) { index++; } string ret = null; if (e is AnonymousFunctionExpr) // function() ... end { AnonymousFunctionExpr f = e as AnonymousFunctionExpr; StringBuilder sb = new StringBuilder(); sb.Append(fromToken(tok[index++], s)); // 'function' sb.Append(fromToken(tok[index++], s)); // '(' for (int i2 = 0; i2 < f.Arguments.Count; i2++) { sb.Append(fromToken(tok[index++], s)); if (i2 != f.Arguments.Count - 1 || f.IsVararg) { sb.Append(fromToken(tok[index++], s) + " "); } } if (f.IsVararg) { sb.Append(fromToken(tok[index++], s)); } sb.Append(fromToken(tok[index++], s)); // ')' if (f.Body.Count > 1) { sb.Append(options.EOL); indent++; sb.Append(DoChunk(f.Body)); sb.Append(nldedent()); } else if (f.Body.Count == 0) { sb.Append(" "); } else { sb.Append(" " + DoStatement(f.Body[0])); sb.Append(" "); } //sb.Append(DoChunk(f.Body)); // Ugh. sb.Append(fromToken(tok[index++], s)); // <end> ret = sb.ToString(); } else if (e is BinOpExpr) { //int i = 0; string left = DoExpr((e as BinOpExpr).Lhs, tok, ref index, s); string op = fromToken(tok[index++], s); string right = DoExpr((e as BinOpExpr).Rhs, tok, ref index, s); ret = string.Format("{0} {1} {2}", left, op, right); } else if (e is BoolExpr) { ret = fromToken(tok[index++], s); } else if (e is CallExpr && (!(e is StringCallExpr) && !(e is TableCallExpr))) { CallExpr c = e as CallExpr; StringBuilder sb = new StringBuilder(); sb.Append(DoExpr(c.Base, tok, ref index, s) // <base> + fromToken(tok[index++], s)); // '(' for (int i = 0; i < c.Arguments.Count; i++) { sb.Append(DoExpr(c.Arguments[i], tok, ref index, s)); if (i != c.Arguments.Count - 1) { sb.Append(fromToken(tok[index++], s)); // ', ' sb.Append(" "); } } sb.Append(fromToken(tok[index++], s)); // ')' ret = sb.ToString(); } else if (e is StringCallExpr) { StringCallExpr sc = e as StringCallExpr; ret = string.Format("{0} {1}", DoExpr(sc.Base, tok, ref index, s), DoExpr(sc.Arguments[0], tok, ref index, s)); } else if (e is TableCallExpr) { TableCallExpr sc = e as TableCallExpr; ret = string.Format("{0} {1}", DoExpr(sc.Base, tok, ref index, s), DoExpr(sc.Arguments[0], tok, ref index, s)); } else if (e is IndexExpr) { IndexExpr i = e as IndexExpr; ret = string.Format("{0}{1}{2}{3}", DoExpr(i.Base, tok, ref index, s), fromToken(tok[index++], s), DoExpr(i.Index, tok, ref index, s), fromToken(tok[index++], s)); } else if (e is InlineFunctionExpression) // |<args>| -> <exprs> { InlineFunctionExpression ife = e as InlineFunctionExpression; StringBuilder sb = new StringBuilder(); sb.Append(fromToken(tok[index++], s)); // '|; for (int i = 0; i < ife.Arguments.Count; i++) { sb.Append(fromToken(tok[index++], s)); // <arg name> if (i != ife.Arguments.Count - 1 || ife.IsVararg) { sb.Append(fromToken(tok[index++], s)); // ',' sb.Append(" "); } } if (ife.IsVararg) { sb.Append(fromToken(tok[index++], s)); // '...' sb.Append(" "); } sb.Append(fromToken(tok[index++], s)); // '|' sb.Append(" "); sb.Append(fromToken(tok[index++], s)); // '->' sb.Append(" "); for (int i2 = 0; i2 < ife.Expressions.Count; i2++) { sb.Append(DoExpr(ife.Expressions[i2], tok, ref index, s)); if (i2 != ife.Expressions.Count - 1) { sb.Append(fromToken(tok[index++], s)); // ',' sb.Append(" "); } } ret = sb.ToString(); } else if (e is TableConstructorKeyExpr) { TableConstructorKeyExpr t = e as TableConstructorKeyExpr; ret = fromToken(tok[index++], s) + DoExpr(t.Key, tok, ref index, s) + fromToken(tok[index++], s) + " " + fromToken(tok[index++], s) + " " + DoExpr(t.Value, tok, ref index, s); } else if (e is MemberExpr) { MemberExpr m = e as MemberExpr; ret = DoExpr(m.Base, tok, ref index, s) + fromToken(tok[index++], s) + fromToken(tok[index++], s); } else if (e is NilExpr) { ret = fromToken(tok[index++], s); } else if (e is NumberExpr) { ret = fromToken(tok[index++], s); } else if (e is StringExpr) { ret = fromToken(tok[index++], s); } else if (e is TableConstructorStringKeyExpr) { TableConstructorStringKeyExpr tcske = e as TableConstructorStringKeyExpr; ret = fromToken(tok[index++], s); // key ret += " "; ret += fromToken(tok[index++], s); // '=' ret += " "; ret += DoExpr(tcske.Value, tok, ref index, s); // value } else if (e is TableConstructorExpr) { TableConstructorExpr t = e as TableConstructorExpr; StringBuilder sb = new StringBuilder(); sb.Append(fromToken(tok[index++], s)); // '{' sb.Append(" "); for (int i = 0; i < t.EntryList.Count; i++) { sb.Append(DoExpr(t.EntryList[i], tok, ref index, s)); if (i != t.EntryList.Count - 1) { sb.Append(fromToken(tok[index++], s)); // ',' sb.Append(" "); } } if (t.EntryList.Count > 0) // empty table constructor is just { } { sb.Append(" "); } sb.Append(fromToken(tok[index++], s)); // '}' ret = sb.ToString(); } else if (e is UnOpExpr) { UnOpExpr u = e as UnOpExpr; string sc = fromToken(tok[index++], s); if (u.Op.Length != 1) { sc += " "; } ret = sc + DoExpr(u.Rhs, tok, ref index, s); } else if (e is TableConstructorValueExpr) { ret = DoExpr(((TableConstructorValueExpr)e).Value, tok, ref index, s); } else if (e is VarargExpr) { ret = fromToken(tok[index++], s); } else if (e is VariableExpression) { ret = fromToken(tok[index++], s); } else if (e is TableConstructorNamedFunctionExpr) { ret = DoStatement(((TableConstructorNamedFunctionExpr)e).Value); } if (ret != null) { if (e.ParenCount > 0) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < e.ParenCount; i++) { sb.Append(fromToken(tok[startP++], s)); } sb.Append(ret); for (int i = 0; i < e.ParenCount; i++) { sb.Append(fromToken(tok[index++], s)); } return(sb.ToString()); } else { return(ret); } } //return string.Format("{0}{1}{2}", "(".Repeat(e.ParenCount), ret, ")".Repeat(e.ParenCount)); throw new NotImplementedException(e.GetType().Name + " is not implemented"); }
string DoExpr(Expression e) { string ret = ""; if (e is AnonymousFunctionExpr) // function() ... end { AnonymousFunctionExpr f = e as AnonymousFunctionExpr; StringBuilder sb = new StringBuilder(); sb.Append("function("); for (int i = 0; i < f.Arguments.Count; i++) { sb.Append(f.Arguments[i].Name); if (i != f.Arguments.Count - 1 || f.IsVararg) { sb.Append(", "); } } if (f.IsVararg) { sb.Append("..."); } sb.Append(")"); if (f.Body.Count > 1) { sb.Append(EOL); indent++; sb.Append(DoChunk(f.Body)); sb.Append(nldedent()); sb.Append("end"); } else if (f.Body.Count == 0) { sb.Append(" end"); } else { sb.Append(" " + DoStatement(f.Body[0])); sb.Append(" end"); } ret = sb.ToString(); } else if (e is BinOpExpr) { BinOpExpr b = e as BinOpExpr; string left = DoExpr(b.Lhs); string op = b.Op; string right = DoExpr(b.Rhs); if (op == "!=") { op = "~="; } if (op == ">>") { ret = string.Format("bit.rshift({0}, {1})", left, right); } else if (op == "<<") { ret = string.Format("bit.lshift({0}, {1})", left, right); } else if (op == "&") { ret = string.Format("bit.band({0}, {1})", left, right); } else if (op == "|") { ret = string.Format("bit.bor({0}, {1})", left, right); } else if (op == "^^") { ret = string.Format("bit.bxor({0}, {1})", left, right); } else { ret = string.Format("{0} {1} {2}", left, op, right); } } else if (e is BoolExpr) { bool val = (e as BoolExpr).Value; ret = val ? "true" : "false"; } else if (e is CallExpr && (!(e is StringCallExpr) && !(e is TableCallExpr))) { CallExpr c = e as CallExpr; StringBuilder sb = new StringBuilder(); sb.Append(DoExpr(c.Base) + "("); for (int i = 0; i < c.Arguments.Count; i++) { sb.Append(DoExpr(c.Arguments[i])); if (i != c.Arguments.Count - 1) { sb.Append(", "); } } sb.Append(")"); ret = sb.ToString(); } else if (e is StringCallExpr) { StringCallExpr s = e as StringCallExpr; ret = string.Format("{0} {1}", DoExpr(s.Base), DoExpr(s.Arguments[0])); } else if (e is TableCallExpr) { TableCallExpr s = e as TableCallExpr; ret = string.Format("{0} {1}", DoExpr(s.Base), DoExpr(s.Arguments[0])); } else if (e is IndexExpr) { IndexExpr i = e as IndexExpr; ret = string.Format("{0}[{1}]", DoExpr(i.Base), DoExpr(i.Index)); } else if (e is InlineFunctionExpression) // |<args>| -> <exprs> { InlineFunctionExpression ife = e as InlineFunctionExpression; StringBuilder sb = new StringBuilder(); sb.Append("function("); for (int i = 0; i < ife.Arguments.Count; i++) { sb.Append(ife.Arguments[i].Name); if (i != ife.Arguments.Count - 1 || ife.IsVararg) { sb.Append(", "); } } if (ife.IsVararg) { sb.Append("..."); } sb.Append(") return "); for (int i2 = 0; i2 < ife.Expressions.Count; i2++) { sb.Append(DoExpr(ife.Expressions[i2])); if (i2 != ife.Expressions.Count - 1) { sb.Append(", "); } } sb.Append(" end"); ret = sb.ToString(); } else if (e is TableConstructorKeyExpr) { TableConstructorKeyExpr t = e as TableConstructorKeyExpr; ret = "[" + DoExpr(t.Key) + "] = " + DoExpr(t.Value); } else if (e is MemberExpr) { MemberExpr m = e as MemberExpr; ret = DoExpr(m.Base) + m.Indexer + m.Ident; } else if (e is NilExpr) { ret = "nil"; } else if (e is NumberExpr) { ret = (e as NumberExpr).Value; ret = ret.Replace("_", ""); } else if (e is StringExpr) { StringExpr se = e as StringExpr; string delim = se.StringType == TokenType.SingleQuoteString ? "'" : se.StringType == TokenType.DoubleQuoteString ? "\"" : "["; if (delim == "[") { // Long strings keep their [=*[ ret = se.Value; } else { ret = delim + se.Value + delim; } } else if (e is TableConstructorStringKeyExpr) { TableConstructorStringKeyExpr tcske = e as TableConstructorStringKeyExpr; ret = tcske.Key + " = " + DoExpr(tcske.Value); } else if (e is TableConstructorExpr) { TableConstructorExpr t = e as TableConstructorExpr; StringBuilder sb = new StringBuilder(); sb.Append("{ "); for (int i = 0; i < t.EntryList.Count; i++) { sb.Append(DoExpr(t.EntryList[i])); if (i != t.EntryList.Count - 1) { sb.Append(", "); } } sb.Append("} "); ret = sb.ToString(); } else if (e is UnOpExpr) { string op = (e as UnOpExpr).Op; if (op == "!") { op = "not"; } string s = op; if (s == "~") { ret = "bit.bnot(" + DoExpr((e as UnOpExpr).Rhs) + ")"; } else if (s == "+") { ret = "math.abs(" + DoExpr((e as UnOpExpr).Rhs) + ")"; } else { if (s.Length != 1) { s += " "; } ret = s + DoExpr((e as UnOpExpr).Rhs); } } else if (e is TableConstructorValueExpr) { ret = DoExpr((e as TableConstructorValueExpr).Value); } else if (e is VarargExpr) { ret = "..."; } else if (e is VariableExpression) { ret = (e as VariableExpression).Var.Name; } else if (e is TableConstructorNamedFunctionExpr) { TableConstructorNamedFunctionExpr fs = e as TableConstructorNamedFunctionExpr; AnonymousFunctionExpr a = new AnonymousFunctionExpr(); a.Arguments = fs.Value.Arguments; a.Arguments.Insert(0, new Variable() { Name = "self", IsGlobal = false, References = -1 }); a.Body = fs.Value.Body; a.IsVararg = fs.Value.IsVararg; ret = DoExpr(fs.Value.Name) + " = " + DoExpr(a); } return(string.Format("{0}{1}{2}", oparens(e.ParenCount), ret, cparens(e.ParenCount))); throw new NotImplementedException(e.GetType().Name + " is not implemented"); }
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); }
Expression ParseSuffixedExpr(Scope scope, bool onlyDotColon = false) { // base primary expression Expression prim = ParsePrimaryExpr(scope); while (true) { if (tok.IsSymbol('.') || tok.IsSymbol(':')) { string symb = tok.Get().Data; // '.' or ':' // TODO: should we allow keywords? if (!tok.Is(TokenType.Ident)) { error("<Ident> expected"); } Token id = tok.Get(); MemberExpr m = new MemberExpr(); m.Base = prim; m.Indexer = symb; m.Ident = id.Data; prim = m; } else if (!onlyDotColon && tok.ConsumeSymbol('[')) { Expression ex = ParseExpr(scope); if (!tok.ConsumeSymbol(']')) { error("']' expected"); } IndexExpr i = new IndexExpr(); i.Base = prim; i.Index = ex; prim = i; } else if (!onlyDotColon && tok.ConsumeSymbol('(')) { List <Expression> args = new List <Expression>(); while (!tok.ConsumeSymbol(')')) { Expression ex = ParseExpr(scope); args.Add(ex); if (!tok.ConsumeSymbol(',')) { if (tok.ConsumeSymbol(')')) { break; } else { error("')' expected"); } } } CallExpr c = new CallExpr(); c.Base = prim; c.Arguments = args; prim = c; } else if (!onlyDotColon && (tok.Is(TokenType.SingleQuoteString) || tok.Is(TokenType.DoubleQuoteString) || tok.Is(TokenType.LongString))) { //string call StringCallExpr e = new StringCallExpr(); e.Base = prim; e.Arguments = new List <Expression> { new StringExpr(tok.Peek().Data) { StringType = tok.Peek().Type } }; tok.Get(); prim = e; } else if (!onlyDotColon && tok.IsSymbol('{')) { // table call Expression ex = ParseExpr(scope); TableCallExpr t = new TableCallExpr(); t.Base = prim; t.Arguments = new List <Expression> { ex }; prim = t; } else { break; } } return(prim); }
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; }