Type getSuffixType(Type t, LuaAST suffix) { if (suffix.Components.ContainsKey("index")) { LuaAST index = suffix.Components["index"]; if (index.Components.ContainsKey("name")) { LuaVariable name = getVariable(index.Components["name"]); if (t.Members.ContainsKey(name.Name)) { return(t.Members[name.Name].Type); } if (t.Methods.ContainsKey(name.Name)) { return(t.Methods[name.Name].ReturnType); } if (t.InnerClasses.ContainsKey(name.Name)) { return(t.InnerClasses[name.Name]); } } } return(t); }
LuaAST parseTableconstructor() { ParserState ps = new ParserState(this); do { if (peek().Type != LuaTokenType.OP_lbrace) { break; } m_pos++; LuaAST rst = new LuaAST(); rst.Name = "tableconstructor"; LuaAST fieldlist = parseFieldlist(); if (fieldlist != null) { rst.Components.Add("fieldlist", fieldlist); } if (peek().Type != LuaTokenType.OP_rbrace) { error("'}' expected"); } m_pos++; rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); return(null); }
void walkAssignExp(LuaAST assignExp) { LuaAST varlist = assignExp.Components["varlist"]; LuaAST explist = assignExp.Components["explist"]; List <LuaVariable> vl = getVariables(varlist); for (int i = 0; i < vl.Count; i++) { LuaVariable var = vl[i]; if (var != null) { Variable v = new Variable(var.Name); if (i >= explist.ComponentGroup.Count) { continue; } else { v.Type = getExpressionType(explist.ComponentGroup[i]); if (v.Type.InternalName == "(UnknownType)") { continue; } } v.StartPos = var.StartPos; m_currentScope.addVariable(v); } } }
LuaAST parseSuffix() { ParserState ps = new ParserState(this); LuaAST rst = new LuaAST(); rst.Name = "suffix"; LuaAST call = parseCall(); if (call != null) { rst.Components.Add("call", call); rst.start = ps.pos; rst.end = m_pos; return(rst); } LuaAST index = parseIndex(); if (index != null) { rst.Components.Add("index", index); rst.start = ps.pos; rst.end = m_pos; return(rst); } ps.restore(); return(null); }
LuaAST parseBiop() { ParserState ps = new ParserState(this); switch (peek().Type) { case LuaTokenType.OP_add: case LuaTokenType.OP_sub: case LuaTokenType.OP_mul: case LuaTokenType.OP_div: case LuaTokenType.OP_pow: case LuaTokenType.OP_mod: case LuaTokenType.OP_doubleDot: case LuaTokenType.OP_lt: case LuaTokenType.OP_le: case LuaTokenType.OP_gt: case LuaTokenType.OP_ge: case LuaTokenType.OP_eq: case LuaTokenType.OP_ne: case LuaTokenType.KW_and: case LuaTokenType.KW_or: LuaAST rst = new LuaAST(); rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return(rst); } ps.restore(); return(null); }
LuaAST parseLaststat() { ParserState ps = new ParserState(this); do { if (peek().Type != LuaTokenType.KW_return) { break; } m_pos++; LuaAST rst = new LuaAST(); rst.Name = "return"; LuaAST explist = parseExplist(); if (explist != null) { rst.Components.Add("explist", explist); } rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); if (peek().Type == LuaTokenType.KW_break) { m_pos++; LuaAST rst = new LuaAST(); rst.Name = "break"; rst.start = ps.pos; rst.end = m_pos; return(rst); } ps.restore(); return(null); }
void walkChuck(LuaAST chunk) { foreach (LuaAST s in chunk.ComponentGroup) { walkStatment(s); } }
LuaAST parseNamelist() { ParserState ps = new ParserState(this); do { LuaAST name = parseName(); if (name == null) { break; } LuaAST rst = new LuaAST(); rst.Name = "namelist"; rst.ComponentGroup.Add(name); while (peek().Type == LuaTokenType.OP_comma) { ParserState nps = new ParserState(this); m_pos++; name = parseName(); if (name == null) { nps.restore(); break; } rst.ComponentGroup.Add(name); } rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); return(null); }
LuaAST parseExplist() { ParserState ps = new ParserState(this); do { LuaAST exp = parseExp(); if (exp == null) { break; } LuaAST rst = new LuaAST(); rst.Name = "explist"; rst.ComponentGroup.Add(exp); while (peek().Type == LuaTokenType.OP_comma) { m_pos++; exp = parseExp(); if (exp == null) { error("expression expected"); } rst.ComponentGroup.Add(exp); } rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); return(null); }
void walkFuncionBody(LuaAST st) { Scope s = new Scope(); s.StartPos = st.start; s.EndPos = st.end; Scope cs = m_currentScope; cs.addChild(s); m_currentScope = s; { if (st.Components.ContainsKey("parlist")) { if (st.Components["parlist"].Components.ContainsKey("namelist")) { List <LuaVariable> vl = getNamelist(st.Components["parlist"].Components["namelist"]); foreach (LuaVariable var in vl) { Variable v = new Variable(var.Name); v.Type = m_ac.Types.NullType; v.StartPos = var.StartPos; m_currentScope.addVariable(v); } } } walkChuck(st.Components["block"]); } m_currentScope = cs; }
LuaAST parseFunction() { ParserState ps = new ParserState(this); do { if (peek().Type != LuaTokenType.KW_function) { break; } m_pos++; LuaAST body = parseFuncbody(); if (body == null) { error("function body expected"); } LuaAST rst = new LuaAST(); rst.Name = "function"; rst.Components.Add("funcbody", body); rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); return(null); }
LuaAST parseFieldlist() { ParserState ps = new ParserState(this); do { LuaAST field = parseField(); if (field == null) { break; } LuaAST rst = new LuaAST(); rst.Name = "fieldlist"; rst.ComponentGroup.Add(field); LuaAST fieldsep = parseFieldsep(); while (fieldsep != null) { field = parseField(); if (field == null) { break; } rst.ComponentGroup.Add(field); fieldsep = parseFieldsep(); } rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); return(null); }
public void walk(LuaAST chunk, AutoCompleteData ac) { m_ac = ac; m_ac.Variables.scope = new Scope(); m_currentScope = m_ac.Variables.scope; m_currentScope.StartPos = chunk.start; m_currentScope.EndPos = chunk.end; walkChuck(chunk); }
void walkLocalAssignExp(LuaAST assignExp) { if (!assignExp.Components.ContainsKey("explist")) { return; } walkAssignExp(assignExp); }
Type getPrefixType(LuaAST prefix) { if (prefix.Components.ContainsKey("exp")) { return(getExpressionType(prefix.Components["exp"])); } return(getNameType(prefix.Components["name"])); }
LuaAST parseExp() { ParserState ps = new ParserState(this); do { LuaAST unop = parseUnop(); if (unop == null) { break; } LuaAST exp = parseExp(); if (exp == null) { error("expression expected"); } LuaAST rst = new LuaAST(); rst.Name = "unopExp"; rst.Components.Add("unop", unop); rst.Components.Add("exp", exp); rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); do { LuaAST value = parseValue(); if (value == null) { break; } LuaAST rst = new LuaAST(); rst.Name = "biopExp"; rst.Components.Add("value", value); LuaAST biop = parseBiop(); if (biop != null) { LuaAST exp = parseExp(); if (exp == null) { error("expression expected"); } rst.Components.Add("biop", biop); rst.Components.Add("exp", exp); } rst.start = ps.pos; rst.end = m_pos; return(rst); }while(false); ps.restore(); return(null); }
Type getFunctionCallType(LuaAST func) { Type t = getPrefixType(func.Components["prefix"]); foreach (LuaAST suffix in func.ComponentGroup) { t = getSuffixType(t, suffix); } return(t); }
LuaAST parseArgs() { ParserState ps = new ParserState(this); LuaAST rst = new LuaAST(); rst.Name = "args"; do { if (peek().Type != LuaTokenType.OP_lparen) { break; } m_pos++; LuaAST explist = parseExplist(); if (explist != null) { rst.Components.Add("explist", explist); } if (peek().Type != LuaTokenType.OP_rparen) { error("')' expected"); } m_pos++; rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); do { LuaAST tc = parseTableconstructor(); if (tc == null) { break; } rst.Components.Add("tableconstructor", tc); rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); if (peek().Type == LuaTokenType.StringLiteral) { rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return(rst); } return(null); }
List <LuaVariable> getNamelist(LuaAST namelist) { List <LuaVariable> rst = new List <LuaVariable>(); foreach (LuaAST v in namelist.ComponentGroup) { LuaVariable var = getVariable(v); rst.Add(var); } return(rst); }
LuaVariable getVariable(LuaAST var) { if (var.Name == "Name") { LuaVariable v = new LuaVariable(); v.Name = Encoding.UTF8.GetString(var.Token.data); v.StartPos = var.start; return(v); } return(null); }
void walkBlock(LuaAST block) { Scope s = new Scope(); s.StartPos = block.start; s.EndPos = block.end; Scope cs = m_currentScope; cs.addChild(s); m_currentScope = s; walkChuck(block); m_currentScope = cs; }
void walkIfExp(LuaAST s) { walkBlock(s.Components["block"]); foreach (LuaAST expblock in s.ComponentGroup) { walkBlock(expblock.Components["block"]); } if (s.Components.ContainsKey("elseBlock")) { walkBlock(s.Components["elseBlock"]); } }
Type getExpressionType(LuaAST exp) { if (exp == null) { return(m_ac.Types.get("nil")); } if (exp.Components.ContainsKey("value")) { return(getValueType(exp.Components["value"])); } return(getExpressionType(exp.Components["exp"])); }
LuaAST parseIndex() { ParserState ps = new ParserState(this); LuaAST rst = new LuaAST(); rst.Name = "index"; do { if (peek().Type != LuaTokenType.OP_lbracket) { break; } m_pos++; LuaAST exp = parseExp(); if (exp == null) { error("expression expected"); } if (peek().Type != LuaTokenType.OP_rbracket) { error("']' expected"); } m_pos++; rst.Components.Add("exp", exp); rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.OP_dot) { break; } m_pos++; LuaAST name = parseName(); if (name == null) { error("name expected"); } rst.Components.Add("name", name); rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); return(null); }
Type getValueType(LuaAST value) { if (value.Token != null) { switch (value.Token.Type) { case LuaTokenType.KW_nil: return(m_ac.Types.get("nil")); case LuaTokenType.KW_false: case LuaTokenType.KW_true: return(m_ac.Types.get("bool")); case LuaTokenType.Number: return(m_ac.Types.get("number")); case LuaTokenType.StringLiteral: return(m_ac.Types.get("string")); case LuaTokenType.OP_ellipsis: return(m_ac.Types.get("object")); } } if (value.Components.ContainsKey("function")) { return(m_ac.Types.get("function")); } if (value.Components.ContainsKey("tableconstructor")) { return(m_ac.Types.get("table")); } if (value.Components.ContainsKey("functioncall")) { return(getFunctionCallType(value.Components["functioncall"])); } if (value.Components.ContainsKey("var")) { return(getVarType(value.Components["var"])); } if (value.Components.ContainsKey("exp")) { return(getExpressionType(value.Components["exp"])); } return(m_ac.Types.get("nil")); }
LuaAST parseCall() { ParserState ps = new ParserState(this); LuaAST rst = new LuaAST(); rst.Name = "call"; do { LuaAST args = parseArgs(); if (args == null) { break; } rst.Components.Add("args", args); rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.OP_colon) { break; } m_pos++; LuaAST name = parseName(); if (name == null) { error("name expected"); } rst.Components.Add("name", name); LuaAST args = parseArgs(); if (args == null) { error("args expected"); } rst.Components.Add("args", args); rst.start = ps.pos; rst.end = m_pos; return(rst); } while (false); ps.restore(); return(null); }
void walkStatment(LuaAST s) { if (s.Name == "assignExp") { walkAssignExp(s); } else if (s.Name == "functioncallExp") { walkFunctioncallExp(s); } else if (s.Name == "doExp") { walkDoExp(s); } else if (s.Name == "whileExp") { walkWhileExp(s); } else if (s.Name == "repeatExp") { walkRepeatExp(s); } else if (s.Name == "ifExp") { walkIfExp(s); } else if (s.Name == "forExp") { walkForExp(s); } else if (s.Name == "forInExp") { walkForInExp(s); } else if (s.Name == "functionExp") { walkFunctionExp(s); } else if (s.Name == "localFunctionExp") { walkLocalFunctionExp(s); } else if (s.Name == "localAssignExp") { walkLocalAssignExp(s); } }
LuaAST parseName() { ParserState ps = new ParserState(this); if (peek().Type == LuaTokenType.Identifier) { LuaAST rst = new LuaAST(); rst.Name = "Name"; rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return(rst); } ps.restore(); return(null); }
Type getNameType(LuaAST n) { string name = Encoding.UTF8.GetString(n.Token.data); Variable v = m_ac.Variables.getVariable(name, n.Token.pos); if (v != null) { return(v.Type); } Function f = m_ac.Variables.getFunction(name); if (f != null) { return(f.ReturnType); } return(m_ac.Types.get(name)); }
LuaAST parseFuncbody() { ParserState ps = new ParserState(this); do { if (peek().Type != LuaTokenType.OP_lparen) { break; } m_pos++; LuaAST rst = new LuaAST(); rst.Name = "funcbody"; LuaAST parlist = parseParlist(); if (parlist != null) { rst.Components.Add("parlist", parlist); } if (peek().Type != LuaTokenType.OP_rparen) { error("')' expected"); } m_pos++; LuaAST block = parseBlock(); if (block == null) { error("block expected"); } rst.Components.Add("block", block); if (peek().Type != LuaTokenType.KW_end) { error("'end' expected"); } m_pos++; rst.start = ps.pos; rst.end = m_pos; return(rst); }while (false); ps.restore(); return(null); }
LuaAST parseFieldsep() { ParserState ps = new ParserState(this); switch (peek().Type) { case LuaTokenType.OP_comma: case LuaTokenType.OP_semicolon: LuaAST rst = new LuaAST(); rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } ps.restore(); return null; }
LuaAST parseFieldlist() { ParserState ps = new ParserState(this); do { LuaAST field = parseField(); if (field == null) break; LuaAST rst = new LuaAST(); rst.Name = "fieldlist"; rst.ComponentGroup.Add(field); LuaAST fieldsep = parseFieldsep(); while (fieldsep != null) { field = parseField(); if (field == null) { break; } rst.ComponentGroup.Add(field); fieldsep = parseFieldsep(); } rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); return null; }
LuaAST parseUnop() { ParserState ps = new ParserState(this); switch (peek().Type) { case LuaTokenType.OP_sub: case LuaTokenType.OP_hash: case LuaTokenType.KW_not: LuaAST rst = new LuaAST(); rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } ps.restore(); return null; }
LuaAST parseBiop() { ParserState ps = new ParserState(this); switch (peek().Type) { case LuaTokenType.OP_add: case LuaTokenType.OP_sub: case LuaTokenType.OP_mul: case LuaTokenType.OP_div: case LuaTokenType.OP_pow: case LuaTokenType.OP_mod: case LuaTokenType.OP_doubleDot: case LuaTokenType.OP_lt: case LuaTokenType.OP_le: case LuaTokenType.OP_gt: case LuaTokenType.OP_ge: case LuaTokenType.OP_eq: case LuaTokenType.OP_ne: case LuaTokenType.KW_and: case LuaTokenType.KW_or: LuaAST rst = new LuaAST(); rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } ps.restore(); return null; }
Type getSuffixType(Type t,LuaAST suffix) { if (suffix.Components.ContainsKey("index")) { LuaAST index = suffix.Components["index"]; if(index.Components.ContainsKey("name")){ LuaVariable name = getVariable(index.Components["name"]); if (t.Members.ContainsKey(name.Name)) { return t.Members[name.Name].Type; } if (t.Methods.ContainsKey(name.Name)) { return t.Methods[name.Name].ReturnType; } if(t.InnerClasses.ContainsKey(name.Name)){ return t.InnerClasses[name.Name]; } } } else if (suffix.Components.ContainsKey("call")) { LuaAST index = suffix.Components["call"]; if (index.Components.ContainsKey("name")) { LuaVariable name = getVariable(index.Components["name"]); if (t.Methods.ContainsKey(name.Name)) { return t.Methods[name.Name].ReturnType; } } } return t; }
Type getFunctionCallType(LuaAST func) { Type t = getPrefixType(func.Components["prefix"]); foreach(LuaAST suffix in func.ComponentGroup){ t = getSuffixType(t, suffix); } return t; }
LuaAST parseFuncbody() { ParserState ps = new ParserState(this); do{ if (peek().Type != LuaTokenType.OP_lparen) break; m_pos++; LuaAST rst = new LuaAST(); rst.Name = "funcbody"; LuaAST parlist = parseParlist(); if (parlist != null) { rst.Components.Add("parlist", parlist); } if (peek().Type != LuaTokenType.OP_rparen) error("')' expected"); m_pos++; LuaAST block = parseBlock(); if (block == null) error("block expected"); rst.Components.Add("block", block); if (peek().Type != LuaTokenType.KW_end) error("'end' expected"); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; }while (false); ps.restore(); return null; }
LuaAST parseVar() { ParserState ps = new ParserState(this); do { LuaAST prefix = parsePrefix(); if (prefix == null) break; LuaAST suffix = parseSuffix(); LuaAST rst = new LuaAST(); rst.Name = "var"; rst.Components.Add("prefix", prefix); while (suffix != null) { rst.ComponentGroup.Add(suffix); suffix = parseSuffix(); } if (rst.ComponentGroup.Count == 0 || !rst.ComponentGroup[rst.ComponentGroup.Count - 1].Components.ContainsKey("index")) break; //error("index expected"); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { LuaAST name = parseName(); if (name != null) return name; } while (false); ps.restore(); return null; }
LuaAST parseIndex() { ParserState ps = new ParserState(this); LuaAST rst = new LuaAST(); rst.Name = "index"; do { if (peek().Type != LuaTokenType.OP_lbracket) break; m_pos++; LuaAST exp = parseExp(); if (exp == null) error("expression expected"); if (peek().Type != LuaTokenType.OP_rbracket) error("']' expected"); m_pos++; rst.Components.Add("exp", exp); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.OP_dot) break; m_pos++; LuaAST name = parseName(); if (name == null) error("name expected"); rst.Components.Add("name", name); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); return null; }
LuaAST parseCall() { ParserState ps = new ParserState(this); LuaAST rst = new LuaAST(); rst.Name = "call"; do { LuaAST args = parseArgs(); if (args == null) break; rst.Components.Add("args", args); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.OP_colon) break; m_pos++; LuaAST name = parseName(); if (name == null) error("name expected"); rst.Components.Add("name", name); LuaAST args = parseArgs(); if (args == null) error("args expected"); rst.Components.Add("args", args); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); return null; }
LuaAST parseExp() { ParserState ps = new ParserState(this); do { LuaAST unop = parseUnop(); if (unop == null) break; LuaAST exp = parseExp(); if (exp == null) error("expression expected"); LuaAST rst = new LuaAST(); rst.Name = "unopExp"; rst.Components.Add("unop", unop); rst.Components.Add("exp", exp); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do{ LuaAST value = parseValue(); if(value == null) break; LuaAST rst =new LuaAST(); rst.Name = "biopExp"; rst.Components.Add("value",value); LuaAST biop = parseBiop(); if(biop != null){ LuaAST exp = parseExp(); if(exp == null) error("expression expected"); rst.Components.Add("biop",biop); rst.Components.Add("exp",exp); } rst.start = ps.pos; rst.end = m_pos; return rst; }while(false); ps.restore(); return null; }
LuaAST parseExplist() { ParserState ps = new ParserState(this); do { LuaAST exp = parseExp(); if (exp == null) break; LuaAST rst = new LuaAST(); rst.Name = "explist"; rst.ComponentGroup.Add(exp); while (peek().Type == LuaTokenType.OP_comma) { m_pos++; exp = parseExp(); if (exp == null) error("expression expected"); rst.ComponentGroup.Add(exp); } rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); return null; }
LuaAST parseNamelist() { ParserState ps = new ParserState(this); do { LuaAST name = parseName(); if (name == null) break; LuaAST rst = new LuaAST(); rst.Name = "namelist"; rst.ComponentGroup.Add(name); while (peek().Type == LuaTokenType.OP_comma) { ParserState nps = new ParserState(this); m_pos++; name = parseName(); if (name == null) { nps.restore(); break; } rst.ComponentGroup.Add(name); } rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); return null; }
LuaAST parseTableconstructor() { ParserState ps = new ParserState(this); do { if (peek().Type != LuaTokenType.OP_lbrace) break; m_pos++; LuaAST rst = new LuaAST(); rst.Name = "tableconstructor"; LuaAST fieldlist = parseFieldlist(); if (fieldlist != null) { rst.Components.Add("fieldlist", fieldlist); } if (peek().Type != LuaTokenType.OP_rbrace) error("'}' expected"); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); return null; }
LuaAST parseFuncname() { ParserState ps = new ParserState(this); do { LuaAST name = parseName(); if (name == null) break; LuaAST rst = new LuaAST(); rst.Name = "funcname"; rst.ComponentGroup.Add(name); while (peek().Type == LuaTokenType.OP_dot) { m_pos++; name = parseName(); if (name == null) error("name expected"); rst.ComponentGroup.Add(name); } if (peek().Type == LuaTokenType.OP_colon) { m_pos++; name = parseName(); if (name == null) error("name expected"); rst.Components.Add("colonName",name); } rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); return null; }
LuaAST parseParlist() { ParserState ps = new ParserState(this); LuaAST rst = new LuaAST(); rst.Name = "parlist"; do { LuaAST namelist = parseNamelist(); if (namelist == null) break; rst.Components.Add("namelist", namelist); if (peek().Type == LuaTokenType.OP_comma) { m_pos++; if (peek().Type != LuaTokenType.OP_ellipsis) error("'...' expected"); rst.Token = peek(); m_pos++; } rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); if (peek().Type == LuaTokenType.OP_ellipsis) { rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } ps.restore(); return null; }
LuaAST parseValue() { ParserState ps = new ParserState(this); LuaAST rst = new LuaAST(); rst.Name = "value"; if (peek().Type == LuaTokenType.KW_nil) { rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } if (peek().Type == LuaTokenType.KW_false) { rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } if (peek().Type == LuaTokenType.KW_true) { rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } if (peek().Type == LuaTokenType.Number) { rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } if (peek().Type == LuaTokenType.StringLiteral) { rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } if (peek().Type == LuaTokenType.OP_ellipsis) { rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } do { LuaAST func = parseFunction(); if (func == null) break; rst.Components.Add("function", func); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { LuaAST tc = parseTableconstructor(); if (tc == null) break; rst.Components.Add("tableconstructor", tc); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { LuaAST fc = parseFunctioncall(); if (fc == null) break; rst.Components.Add("functioncall", fc); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { LuaAST var = parseVar(); if (var == null) break; rst.Components.Add("var", var); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); do { if (peek().Type != LuaTokenType.OP_lparen) break; m_pos++; LuaAST exp = parseExp(); if (exp == null) error ("expression expected"); rst.Components.Add("exp", exp); if (peek().Type != LuaTokenType.OP_rparen) error("')' expected"); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); return null; }
LuaAST parseSuffix() { ParserState ps = new ParserState(this); LuaAST rst = new LuaAST(); rst.Name = "suffix"; LuaAST call = parseCall(); if (call != null) { rst.Components.Add("call", call); rst.start = ps.pos; rst.end = m_pos; return rst; } LuaAST index = parseIndex(); if (index != null) { rst.Components.Add("index", index); rst.start = ps.pos; rst.end = m_pos; return rst; } ps.restore(); return null; }
LuaAST parseLaststat() { ParserState ps = new ParserState(this); do { if (peek().Type != LuaTokenType.KW_return) break; m_pos++; LuaAST rst = new LuaAST(); rst.Name = "return"; LuaAST explist = parseExplist(); if (explist != null) { rst.Components.Add("explist", explist); } rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); if (peek().Type == LuaTokenType.KW_break) { m_pos++; LuaAST rst = new LuaAST(); rst.Name = "break"; rst.start = ps.pos; rst.end = m_pos; return rst; } ps.restore(); return null; }
void walkAssignExp(LuaAST assignExp) { LuaAST varlist = assignExp.Components["varlist"]; LuaAST explist = assignExp.Components["explist"]; List<LuaVariable> vl = getVariables(varlist); for (int i = 0; i < vl.Count; i++) { LuaVariable var = vl[i]; if (var != null) { Variable v = new Variable(var.Name); if (i >= explist.ComponentGroup.Count) { continue; } else { v.Type = getExpressionType(explist.ComponentGroup[i]); if (v.Type.InternalName == "(UnknownType)") { continue; } } v.StartPos = var.StartPos; m_currentScope.addVariable(v); } } }
LuaAST parseFunctioncall() { ParserState ps = new ParserState(this); do { LuaAST prefix = parsePrefix(); if (prefix == null) break; LuaAST rst = new LuaAST(); rst.Components.Add("prefix", prefix); LuaAST suffix = parseSuffix(); while (suffix!=null) { rst.ComponentGroup.Add(suffix); suffix = parseSuffix(); } if (rst.ComponentGroup.Count == 0) break; LuaAST last = rst.ComponentGroup[rst.ComponentGroup.Count-1]; if (!last.Components.ContainsKey("call")) break; rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); return null; }
LuaAST parseArgs() { ParserState ps = new ParserState(this); LuaAST rst = new LuaAST(); rst.Name = "args"; do { if (peek().Type != LuaTokenType.OP_lparen) break; m_pos++; LuaAST explist = parseExplist(); if (explist != null) rst.Components.Add("explist",explist); if (peek().Type != LuaTokenType.OP_rparen) error("')' expected"); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { LuaAST tc = parseTableconstructor(); if (tc == null) break; rst.Components.Add("tableconstructor", tc); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); if (peek().Type == LuaTokenType.StringLiteral) { rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } return null; }
LuaAST parseFunction() { ParserState ps = new ParserState(this); do { if (peek().Type != LuaTokenType.KW_function) break; m_pos++; LuaAST body = parseFuncbody(); if (body == null) error("function body expected"); LuaAST rst = new LuaAST(); rst.Name = "function"; rst.Components.Add("funcbody", body); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); return null; }
Type getPrefixType(LuaAST prefix) { if (prefix.Components.ContainsKey("exp")) { return getExpressionType(prefix.Components["exp"]); } return getNameType(prefix.Components["name"]); }
LuaAST parseChunk() { ParserState ps = new ParserState(this); int i = 0; LuaAST rst = new LuaAST(); rst.start = m_pos; rst.Name = "chunk"; while(true) { ParserState statState = new ParserState(this); try { LuaAST stat = parseStat(); if (stat == null) { LuaAST laststat = parseLaststat(); if (laststat != null) { rst.Components.Add("laststat", laststat); if (peek().Type == LuaTokenType.OP_semicolon) { m_pos++; } } break; } rst.ComponentGroup.Add(stat); if (peek().Type == LuaTokenType.OP_semicolon) { m_pos++; } } catch (Exception e) { if (errMsg == null) errMsg = e.Message; statState.restore(); int line = peek().line; while (peek().Type != LuaTokenType.EOF && peek().line <= line) { m_pos++; } if (peek().Type == LuaTokenType.EOF) { break; } } } rst.end = m_pos; return rst; ps.restore(); return null; }
LuaAST parseStat() { ParserState ps = new ParserState(this); do { LuaAST varlist = parseVarlist(); if (varlist == null) break; if (peek().Type != LuaTokenType.OP_assign) break; m_pos++; LuaAST explist = parseExplist(); if (explist == null) break; LuaAST rst = new LuaAST(); rst.Name = "assignExp"; rst.start = ps.pos; rst.end = m_pos; rst.Components.Add("varlist", varlist); rst.Components.Add("explist", explist); return rst; } while (false); ps.restore(); do { LuaAST functioncall = parseFunctioncall(); if (functioncall == null) break; LuaAST rst = new LuaAST(); rst.Name = "functioncallExp"; rst.Components.Add("functioncall", functioncall); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.KW_do) break; m_pos++; LuaAST block = parseBlock(); if (block == null) error("block expected"); if (peek().Type != LuaTokenType.KW_end) error("'end' expected"); m_pos++; LuaAST rst = new LuaAST(); rst.Name = "doExp"; rst.Components.Add("block", block); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.KW_while) break; m_pos++; LuaAST exp = parseExp(); if (exp == null) error("expression expected"); if (peek().Type != LuaTokenType.KW_do) error("'do' expected"); m_pos++; LuaAST block = parseBlock(); if (block == null) break; if (peek().Type != LuaTokenType.KW_end) error("'end' expected"); m_pos++; LuaAST rst = new LuaAST(); rst.Name = "whileExp"; rst.Components.Add("exp", exp); rst.Components.Add("block", block); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.KW_repeat) break; m_pos++; LuaAST block = parseBlock(); if (block == null) error("block expected"); ; if (peek().Type != LuaTokenType.KW_until) error("'until' expected"); m_pos++; LuaAST exp = parseExp(); if (exp == null) error("expression expected"); ; LuaAST rst = new LuaAST(); rst.Name = "repeatExp"; rst.Components.Add("exp", exp); rst.Components.Add("block", block); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.KW_if) break; m_pos++; LuaAST exp = parseExp(); if (exp == null) error("expression expected"); if (peek().Type != LuaTokenType.KW_then) error("'then' expected"); m_pos++; LuaAST block = parseBlock(); if (block == null) error("block expected"); LuaAST rst = new LuaAST(); rst.Name = "ifExp"; rst.Components.Add("exp", exp); rst.Components.Add("block", block); while (peek().Type == LuaTokenType.KW_elseif) { m_pos++; LuaAST expblock = new LuaAST(); expblock.Name = "expblock"; LuaAST elexp = parseExp(); if(elexp == null) error("expression expected"); expblock.Components.Add("exp", elexp); if (peek().Type != LuaTokenType.KW_then) error("'then' expected"); m_pos++; LuaAST elblock = parseBlock(); if (elblock == null) error("block expected"); expblock.Components.Add("block", elblock); rst.ComponentGroup.Add(expblock); } if (peek().Type == LuaTokenType.KW_else) { m_pos++; LuaAST elblock = parseBlock(); if (elblock == null) error("block expected"); rst.Components.Add("elseBlock", elblock); } if (peek().Type != LuaTokenType.KW_end) error("'end' expected"); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.KW_for) break; m_pos++; LuaAST name = parseName(); if (name == null) break; if (peek().Type != LuaTokenType.OP_assign) break; m_pos++; LuaAST initExp = parseExp(); if (initExp == null) error("expression expected"); if (peek().Type != LuaTokenType.OP_comma) error("',' expected"); m_pos++; LuaAST condExp = parseExp(); if (condExp == null) error("expression expected"); LuaAST rst = new LuaAST(); rst.Name = "forExp"; rst.Components.Add("name", name); rst.Components.Add("initExp", initExp); rst.Components.Add("condExp", condExp); if (peek().Type == LuaTokenType.OP_comma) { m_pos++; LuaAST stepExp = parseExp(); if (stepExp == null) error("expression expected"); rst.Components.Add("stepExp", stepExp); } if (peek().Type != LuaTokenType.KW_do) error("'do' expected"); m_pos++; LuaAST block = parseBlock(); if (block == null) error("block expected"); rst.Components.Add("block", block); if (peek().Type != LuaTokenType.KW_end) error("'end' expected"); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.KW_for) break; m_pos++; LuaAST namelist = parseNamelist(); if (namelist == null) error("name or namelist expected"); if (peek().Type != LuaTokenType.KW_in) error("'in' expected"); m_pos++; LuaAST explist = parseExplist(); if (explist == null) error("expression list expected"); LuaAST rst = new LuaAST(); rst.Name = "forInExp"; rst.Components.Add("namelist", namelist); rst.Components.Add("explist", explist); if (peek().Type != LuaTokenType.KW_do) error("'do' expected"); m_pos++; LuaAST block = parseBlock(); if (block == null) error("block expected"); rst.Components.Add("block", block); if (peek().Type != LuaTokenType.KW_end) error("'end' expected"); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.KW_function) break; m_pos++; LuaAST funcname = parseFuncname(); if (funcname == null) error("function name expected"); LuaAST funcbody = parseFuncbody(); if (funcbody == null) error("function body expected"); LuaAST rst = new LuaAST(); rst.Name = "functionExp"; rst.Components.Add("funcname", funcname); rst.Components.Add("funcbody", funcbody); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.KW_local) break; m_pos++; if (peek().Type != LuaTokenType.KW_function) break; m_pos++; LuaAST funcname = parseFuncname(); if (funcname == null) error("function name expected"); LuaAST funcbody = parseFuncbody(); if (funcbody == null) error("function body expected"); LuaAST rst = new LuaAST(); rst.Name = "localFunctionExp"; rst.Components.Add("funcname", funcname); rst.Components.Add("funcbody", funcbody); rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); do { if (peek().Type != LuaTokenType.KW_local) break; m_pos++; LuaAST varlist = parseVarlist(); if (varlist == null) error("name expected"); ; LuaAST rst = new LuaAST(); rst.Name = "localAssignExp"; rst.Components.Add("varlist", varlist); if (peek().Type == LuaTokenType.OP_assign) { m_pos++; LuaAST explist = parseExplist(); if (explist == null) error("expression expected"); rst.Components.Add("explist", explist); } rst.start = ps.pos; rst.end = m_pos; return rst; } while (false); ps.restore(); //allow id-expression do{ return parseName(); }while(false); ps.restore(); return null; }
LuaAST parseName() { ParserState ps = new ParserState(this); if (peek().Type == LuaTokenType.Identifier) { LuaAST rst = new LuaAST(); rst.Name = "Name"; rst.Token = peek(); m_pos++; rst.start = ps.pos; rst.end = m_pos; return rst; } ps.restore(); return null; }