public static EcmaHeadObject ToArray(EcmaState state, List <Object> item) { ArrayIntstance array = new ArrayIntstance(state, new EcmaValue[0]); for (int i = 0; i < item.Count; i++) { if (item[i] is EcmaHeadObject) { array.Put(i.ToString(), EcmaValue.Object(item[i] as EcmaHeadObject)); } else if (item[i] is String) { array.Put(i.ToString(), EcmaValue.String(item[i] as String)); } else if (item[i] is Boolean) { array.Put(i.ToString(), EcmaValue.Boolean((bool)item[i])); } else if (item[i] is Double) { array.Put(i.ToString(), EcmaValue.Number((double)item[i])); } else if (item[i] == null) { array.Put(i.ToString(), EcmaValue.Null()); } else { throw new EcmaRuntimeException("Could not convert " + item[i].GetType().FullName + " to ecma value"); } } return(array); }
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); } }
public static EcmaValue DoRelational(EcmaState state, EcmaValue left, EcmaValue right) { object l = left.ToPrimitiv(state); object r = right.ToPrimitiv(state); if (l is String && r is String) { string ls = l as String; string rs = r as String; if (ls.IndexOf(rs) == 0) { return(EcmaValue.Boolean(false)); } if (rs.IndexOf(ls) == 0) { return(EcmaValue.Boolean(true)); } char[] lc = ls.ToCharArray(); char[] rc = rs.ToCharArray(); for (int i = 0; i < Math.Min(ls.Length, rs.Length); i++) { if (lc[i] > rc[i]) { return(EcmaValue.Boolean(false)); } } return(EcmaValue.Boolean(true)); } double x = left.ToNumber(state); double y = right.ToNumber(state); if (Double.IsNaN(x) || Double.IsNaN(y)) { return(EcmaValue.Undefined()); } if (x == y) { return(EcmaValue.Boolean(false)); } if (x == -0 && y == +0 || x == +0 && y == -0) { return(EcmaValue.Boolean(false)); } if (Double.IsPositiveInfinity(x) || Double.IsNegativeInfinity(y)) { return(EcmaValue.Boolean(false)); } if (Double.IsNegativeInfinity(x) || Double.IsPositiveInfinity(y)) { return(EcmaValue.Boolean(true)); } return(EcmaValue.Boolean(y > x)); }