private EcmaStatment GetFor(EcmaTokenizer token) { token.Next().Excepect(TokenType.Punctor, "("); ExpresionData first = new ExpresionData(ExpresionType.Null); if (token.Next().IsNot(TokenType.Punctor, ";")) { if (token.Current().Is(TokenType.Keyword, "var")) { token.Next(); first = VariableDeclarationList(token); } else { first = Expresion(token); } } EcmaStatment current = null; if (token.Current().Is(TokenType.Keyword, "in")) { token.Next(); current = new EcmaStatment(EcmaStatmentType.ForIn); current.Expresion = first; current.Second = Expresion(token); } else { token.Current().Excepect(TokenType.Punctor, ";"); token.Next(); current = new EcmaStatment(EcmaStatmentType.For); current.Expresion = first; if (token.Current().IsNot(TokenType.Punctor, ";")) { current.Second = Expresion(token); token.Current().Excepect(TokenType.Punctor, ";"); } else { current.Second = new ExpresionData(ExpresionType.Null); } if (token.Next().IsNot(TokenType.Punctor, ")")) { current.Tree = Expresion(token); } else { current.Tree = new ExpresionData(ExpresionType.Null); } } token.Current().Excepect(TokenType.Punctor, ")"); token.Next(); current.Statment = GetStatment(token); return(current); }
private ExpresionData NewExpression(EcmaTokenizer token) { ExpresionData exp = new ExpresionData(ExpresionType.New); token.Next(); exp.Left = PrimaryExpresion(token); token.Current().Excepect(TokenType.Punctor, "("); exp.Arg = Arguments(token); return(exp); }
private ExpresionData PrimaryExpresion(EcmaTokenizer token) { TokenBuffer buf = token.Current(); token.Next(); if (buf.Is(TokenType.Keyword, "this")) { return(new ExpresionData(ExpresionType.This)); } if (buf.Is(TokenType.Number)) { ExpresionData n = new ExpresionData(ExpresionType.Number); n.Sign = buf.Context; return(n); } if (buf.Is(TokenType.Null)) { return(new ExpresionData(ExpresionType.Null)); } if (buf.Is(TokenType.Bool)) { ExpresionData b = new ExpresionData(ExpresionType.Bool); b.Sign = buf.Context; return(b); } if (buf.Is(TokenType.Identify)) { ExpresionData identify = new ExpresionData(ExpresionType.Identify); identify.Name = buf.Context; return(identify); } if (buf.Is(TokenType.String)) { ExpresionData str = new ExpresionData(ExpresionType.String); str.Sign = buf.Context; return(str); } if (buf.Is(TokenType.Punctor, "(")) { ExpresionData p = Expresion(token); token.Current().Excepect(TokenType.Punctor, ")"); token.Next(); return(p); } throw new EcmaRuntimeException("Unknown token detected " + buf.Context + "(" + buf.Type.ToString() + ") on line " + buf.LineStart); }
private ExpresionData UnaryExpression(EcmaTokenizer token) { if (token.Current().Is(TokenType.Keyword, new string[] { "delete", "void", "typeof" }) || token.Current().Is(TokenType.Punctor, new string[] { "++", "--", "+", "-", "~", "!" })) { ExpresionData buf = new ExpresionData(ExpresionType.Unary); buf.Sign = token.Current().Context; token.Next(); buf.Left = UnaryExpression(token); return(buf); } return(PostfixExpression(token)); }
private ExpresionData PostfixExpression(EcmaTokenizer token) { ExpresionData exp = LeftHandSideExpression(token); if (token.Current().Is(TokenType.Punctor, new string[] { "--", "++" })) { ExpresionData buf = new ExpresionData(ExpresionType.Unary); buf.Sign = token.Current().Context; buf.Left = exp; token.Next(); return(buf); } return(exp); }
private ExpresionData BitwiseANDExpression(EcmaTokenizer token) { ExpresionData exp = EqualityExpression(token); if (token.Current().Is(TokenType.Punctor, "&")) { token.Next(); ExpresionData buf = new ExpresionData(ExpresionType.BAND); buf.Left = exp; buf.Right = BitwiseANDExpression(token); return(buf); } return(exp); }
private ExpresionData LogicalORExpression(EcmaTokenizer token) { ExpresionData exp = LogicalANDExpression(token); if (token.Current().Is(TokenType.Punctor, "||")) { token.Next(); ExpresionData buf = new ExpresionData(ExpresionType.Or); buf.Left = exp; buf.Right = LogicalORExpression(token); return(buf); } return(exp); }
private ExpresionData MultiplicativeExpression(EcmaTokenizer token) { ExpresionData exp = UnaryExpression(token); if (token.Current().Is(TokenType.Punctor, new string[] { "*", "/", "%" })) { ExpresionData buf = new ExpresionData(ExpresionType.Multiplicative); buf.Sign = token.Current().Context; token.Next(); buf.Left = exp; buf.Right = MultiplicativeExpression(token); return(buf); } return(exp); }
private ExpresionData RelationalExpression(EcmaTokenizer token) { ExpresionData exp = ShiftExpression(token); if (token.Current().Is(TokenType.Punctor, RelationalOperator)) { ExpresionData buf = new ExpresionData(ExpresionType.Relational); buf.Left = exp; buf.Sign = token.Current().Context; token.Next(); buf.Right = ShiftExpression(token); return(buf); } return(exp); }
private ExpresionData EqualityExpression(EcmaTokenizer token) { ExpresionData exp = RelationalExpression(token); if (token.Current().Is(TokenType.Punctor, new string[] { "==", "!=" })) { ExpresionData buf = new ExpresionData(ExpresionType.Equlity); buf.Left = exp; buf.Sign = token.Current().Context; token.Next(); buf.Right = RelationalExpression(token); return(buf); } return(exp); }
private ExpresionData AssignmentExpression(EcmaTokenizer token) { ExpresionData exp = ConditionalExpression(token); if (token.Current().Is(TokenType.Punctor, AssignOperator)) { ExpresionData buf = new ExpresionData(ExpresionType.Assign); buf.Left = exp; buf.Sign = token.Current().Context; token.Next(); buf.Right = AssignmentExpression(token); return(buf); } return(exp); }
private ExpresionData VariableDeclarationList(EcmaTokenizer token) { List <ExpresionData> list = new List <ExpresionData>(); ExpresionData exp; token.Current().Excepect(TokenType.Identify); exp = new ExpresionData(ExpresionType.Assign); ExpresionData identify = new ExpresionData(ExpresionType.Identify); identify.Name = token.Current().Context; exp.Left = identify; exp.Sign = "="; if (token.Next().Is(TokenType.Punctor, "=")) { token.Next(); exp.Right = AssignmentExpression(token); } else { exp.Right = new ExpresionData(ExpresionType.Null); } list.Add(exp); while (token.Current().Is(TokenType.Punctor, ",")) { exp = new ExpresionData(ExpresionType.Assign); token.Next().Excepect(TokenType.Identify); identify = new ExpresionData(ExpresionType.Identify); identify.Name = token.Current().Context; exp.Left = identify; exp.Sign = "="; if (token.Next().Is(TokenType.Punctor, "=")) { token.Next(); exp.Right = AssignmentExpression(token); } else { exp.Right = new ExpresionData(ExpresionType.Null); } list.Add(exp); } ExpresionData varList = new ExpresionData(ExpresionType.VarList); varList.Multi = list; return(varList); }
private ExpresionData ConditionalExpression(EcmaTokenizer token) { ExpresionData exp = LogicalORExpression(token); if (token.Current().Is(TokenType.Punctor, "?")) { token.Next(); ExpresionData buf = new ExpresionData(ExpresionType.Conditional); buf.Test = exp; buf.Left = AssignmentExpression(token); token.Current().Excepect(TokenType.Punctor, ":"); token.Next(); buf.Right = AssignmentExpression(token); return(buf); } return(exp); }
private ExpresionData Expresion(EcmaTokenizer token) { ExpresionData expresion = AssignmentExpression(token); if (token.Current().Is(TokenType.Punctor, ",")) { ExpresionData buffer = new ExpresionData(ExpresionType.MultiExpresion); buffer.Multi = new List <ExpresionData>(); buffer.Multi.Add(expresion); while (token.Current().Is(TokenType.Punctor, ",")) { token.Next(); buffer.Multi.Add(AssignmentExpression(token)); } return(buffer); } return(expresion); }
private ExpresionData LeftHandSideExpression(EcmaTokenizer token) { if (token.Current().Is(TokenType.Keyword, "new")) { return(NewExpression(token)); } ExpresionData exp = PrimaryExpresion(token); ExpresionData buf = null; while (token.Current().Is(TokenType.Punctor, new string[] { ".", "(", "[" })) { switch (token.Current().Context) { case ".": token.Next().Excepect(TokenType.Identify); buf = new ExpresionData(ExpresionType.ObjGet); buf.Left = exp; buf.Sign = token.Current().Context; token.Next(); exp = buf; break; case "[": token.Next(); buf = new ExpresionData(ExpresionType.ItemGet); buf.Left = exp; buf.Right = Expresion(token); token.Current().Excepect(TokenType.Punctor, "]"); token.Next(); break; case "(": buf = new ExpresionData(ExpresionType.Call); buf.Left = exp; buf.Arg = Arguments(token); break; } exp = buf; } return(exp); }
private static EcmaValue EvulateExpresion(EcmaState state, ExpresionData expresion) { EcmaValue value = null; EcmaHeadObject obj; switch (expresion.Type) { case ExpresionType.MultiExpresion: for (int i = 0; i < expresion.Multi.Count; i++) { value = Reference.GetValue(EvulateExpresion(state, expresion.Multi[i])); } return(value); case ExpresionType.Assign: if (expresion.Sign == "=") { EcmaValue ai = EvulateExpresion(state, expresion.Left); value = Reference.GetValue(EvulateExpresion(state, expresion.Right)); Reference.PutValue(ai, value, state.GlobalObject); return(value); } else { EcmaValue sa = EvulateExpresion(state, expresion.Left); value = Reference.GetValue(EvulateExpresion(state, expresion.Right)); value = EcmaMath.Math(state, Reference.GetValue(sa), expresion.Sign.Substring(0, 1), value); Reference.PutValue(sa, value, state.GlobalObject); return(value); } case ExpresionType.Conditional: return(Reference.GetValue(EvulateExpresion(state, expresion.Test)).ToBoolean(state) ? Reference.GetValue(EvulateExpresion(state, expresion.Left)) : Reference.GetValue(EvulateExpresion(state, expresion.Right))); case ExpresionType.Or: value = Reference.GetValue(EvulateExpresion(state, expresion.Left)); if (value.ToBoolean(state)) { return(value); } return(Reference.GetValue(EvulateExpresion(state, expresion.Right))); case ExpresionType.AND: value = Reference.GetValue(EvulateExpresion(state, expresion.Left)); if (!value.ToBoolean(state)) { return(value); } return(Reference.GetValue(EvulateExpresion(state, expresion.Right))); case ExpresionType.BOR: return(EcmaMath.Math(state, Reference.GetValue(EvulateExpresion(state, expresion.Left)), "|", Reference.GetValue(EvulateExpresion(state, expresion.Right)))); case ExpresionType.XOR: return(EcmaMath.Math(state, Reference.GetValue(EvulateExpresion(state, expresion.Left)), "^", Reference.GetValue(EvulateExpresion(state, expresion.Right)))); case ExpresionType.BAND: return(EcmaMath.Math(state, Reference.GetValue(EvulateExpresion(state, expresion.Left)), "&", Reference.GetValue(EvulateExpresion(state, expresion.Right)))); case ExpresionType.Equlity: bool er = EcmaEquel.IsEquel(state, Reference.GetValue(EvulateExpresion(state, expresion.Left)), Reference.GetValue(EvulateExpresion(state, expresion.Right))); return(EcmaValue.Boolean(expresion.Sign == "==" ? er : !er)); case ExpresionType.Relational: if (expresion.Sign == "<") { value = EcmaRelational.DoRelational(state, Reference.GetValue(EvulateExpresion(state, expresion.Left)), Reference.GetValue(EvulateExpresion(state, expresion.Right))); if (value.IsUndefined()) { return(EcmaValue.Boolean(false)); } return(value); } else if (expresion.Sign == ">") { value = Reference.GetValue(EvulateExpresion(state, expresion.Left)); value = EcmaRelational.DoRelational(state, Reference.GetValue(EvulateExpresion(state, expresion.Right)), value); if (value.IsUndefined()) { return(EcmaValue.Boolean(false)); } return(value); } else if (expresion.Sign == "<=") { value = EcmaRelational.DoRelational(state, Reference.GetValue(EvulateExpresion(state, expresion.Right)), Reference.GetValue(EvulateExpresion(state, expresion.Left))); if (value.IsBoolean() && value.ToBoolean(state) || value.IsUndefined()) { return(EcmaValue.Boolean(false)); } return(EcmaValue.Boolean(true)); } else if (expresion.Sign == ">=") { value = EcmaRelational.DoRelational(state, Reference.GetValue(EvulateExpresion(state, expresion.Left)), Reference.GetValue(EvulateExpresion(state, expresion.Right))); if (value.IsBoolean() && value.ToBoolean(state) || value.IsUndefined()) { return(EcmaValue.Boolean(false)); } return(EcmaValue.Boolean(true)); } return(EcmaValue.Boolean(false)); case ExpresionType.Shift: return(EcmaMath.Math(state, Reference.GetValue(EvulateExpresion(state, expresion.Left)), expresion.Sign, Reference.GetValue(EvulateExpresion(state, expresion.Right)))); case ExpresionType.Additive: return(EcmaMath.Math(state, Reference.GetValue(EvulateExpresion(state, expresion.Left)), expresion.Sign, Reference.GetValue(EvulateExpresion(state, expresion.Right)))); case ExpresionType.Multiplicative: return(EcmaMath.Math(state, Reference.GetValue(EvulateExpresion(state, expresion.Left)), expresion.Sign, Reference.GetValue(EvulateExpresion(state, expresion.Right)))); case ExpresionType.Unary: value = EvulateExpresion(state, expresion.Left); switch (expresion.Sign) { case "delete": return(EcmaValue.Boolean(Reference.GetBase(value).Delete(Reference.GetPropertyName(value)))); case "void": Reference.GetValue(value); return(EcmaValue.Undefined()); case "typeof": if (value.IsRefrence() && Reference.GetBase(value) == null) { return(EcmaValue.String("undefined")); } value = Reference.GetValue(value); if (value.IsObject()) { obj = value.ToObject(state); if (obj is ICallable) { return(EcmaValue.String("function")); } } return(EcmaValue.String(value.Type().ToString().ToLower())); case "++": double ul = Reference.GetValue(EvulateExpresion(state, expresion.Left)).ToNumber(state); Reference.PutValue(value, EcmaValue.Number(ul + 1), state.GlobalObject); return(EcmaValue.Number(ul + 1)); case "--": double nul = Reference.GetValue(EvulateExpresion(state, expresion.Left)).ToNumber(state); Reference.PutValue(value, EcmaValue.Number(nul + 1), state.GlobalObject); return(EcmaValue.Number(nul + 1)); case "+": return(EcmaValue.Number(+Reference.GetValue(value).ToNumber(state))); case "-": return(EcmaValue.Number(-Reference.GetValue(value).ToNumber(state))); case "~": return(EcmaValue.Number(~Reference.GetValue(value).ToInt32(state))); case "!": return(EcmaValue.Boolean(!Reference.GetValue(value).ToBoolean(state))); default: throw new EcmaRuntimeException("Unary evulation out of sync. Unknown sign: " + expresion.Sign); } case ExpresionType.ItemGet: obj = Reference.GetValue(EvulateExpresion(state, expresion.Left)).ToObject(state); return(EcmaValue.Reference(new Reference( Reference.GetValue(EvulateExpresion(state, expresion.Right)).ToString(state), obj ))); case ExpresionType.ObjGet: return(EcmaValue.Reference(new Reference( expresion.Sign, Reference.GetValue(EvulateExpresion(state, expresion.Left)).ToObject(state) ))); case ExpresionType.New: value = Reference.GetValue(EvulateExpresion(state, expresion.Left)); if (!value.IsObject()) { throw new EcmaRuntimeException("After 'new' keyword there must be a object"); } obj = value.ToObject(state); if (!(obj is IConstruct)) { throw new EcmaRuntimeException("Object dont implements Constructor"); } value = (obj as IConstruct).Construct(GetArguments(state, obj, expresion.Arg)); if (!value.IsObject()) { throw new EcmaRuntimeException("The constructor dont return a object"); } return(value); case ExpresionType.Call: EcmaValue func = EvulateExpresion(state, expresion.Left); value = Reference.GetValue(func); obj = value.ToObject(state); if (!(obj is ICallable)) { throw new EcmaRuntimeException("The object dont implements Call"); } EcmaHeadObject self; if (func.IsRefrence()) { self = Reference.GetBase(func); } else { self = null; } return((obj as ICallable).Call(self, GetArguments(state, obj, expresion.Arg))); case ExpresionType.This: return(EcmaValue.Object(state.GetThis())); case ExpresionType.Identify: return(EcmaValue.Reference(state.GetIdentify(expresion.Name))); case ExpresionType.Number: return(EcmaValue.Number(Double.Parse(expresion.Sign))); case ExpresionType.Null: return(EcmaValue.Undefined()); case ExpresionType.Bool: return(EcmaValue.Boolean(expresion.Sign == "true")); case ExpresionType.String: return(EcmaValue.String(expresion.Sign)); case ExpresionType.VarList: for (int i = 0; i < expresion.Multi.Count; i++) { value = EvulateExpresion(state, expresion.Multi[i]); } return(value); default: throw new EcmaRuntimeException("Evulator expresion out of sync. Unknown expresion type: " + expresion.Type); } }