public static ICollection <eeObject> Generate(eeNumber start, eeNumber stop, eeNumber step) { ICollection <eeObject> rangeObj = new List <eeObject>(); if (start < stop) { for (eeNumber i = start; i <= stop; i += step.Copy()) { rangeObj.Add(eeObject.newNumberObject(i.Copy())); } } else if (stop < start) { for (eeNumber i = start; i >= stop; i -= step.Copy()) { rangeObj.Add(eeObject.newNumberObject(i.Copy())); } } else // they're equal { rangeObj.Add(eeObject.newNumberObject(start.Copy())); } return(rangeObj); }
public static eeObject Multiply(eeObject exp1, eeObject exp2) { bool isExp1 = false; List <eeObject> list; eeObject nonlist; if (exp1.type == eeObjectType.LIST && exp2.type == eeObjectType.NUMBER) { isExp1 = true; list = (List <eeObject>)exp1.value; nonlist = exp2; } else if (exp1.type == eeObjectType.NUMBER && exp2.type == eeObjectType.LIST) { list = (List <eeObject>)exp2.value; nonlist = exp1; } else { throw new Exception("This shouldn't happen"); } var listCount = list.Count(); for (eeNumber i = new eeNumber(0); i < nonlist.AsNumber(); i += new eeNumber(1)) { for (int j = 0; j < listCount; j++) { list.Add(list[j]); } } return(isExp1 ? exp1 : exp2); }
public override eeObject VisitRepeat_loop([NotNull] EelooParser.Repeat_loopContext ctx) { var count = Visit(ctx.exp()); if (count.type != eeObjectType.NUMBER || count.AsNumber() < eeNumber.ONE) { throw new Exception("Cannot repeat a non-positive integer number of times."); } var scope = new Scope(Interpreter.currentScope, ctx); scope.ScopeThis(); for (eeNumber i = new eeNumber(0); i < count.AsNumber(); i += eeNumber.ONE) { var codeblock = Visit(ctx.lines()); // If there is a return statement inside the loop if (codeblock != null) { Scope.unScope(scope); return(codeblock); } } Scope.unScope(scope); return(eeObject.None); }
public static eeObject newNumberObject(eeNumber value, string modifier = null) { return(new eeObject(value) { type = eeObjectType.NUMBER, modifier = modifier, methods = DefaultMethods.numberBuiltInMethods }); }
private int Convert_eeNum(eeNumber num) { // workaround for now to get eeNumbers to work with c#'s arrays int indexValue; for (indexValue = 0; new eeNumber(indexValue) < num; ++indexValue) { ; } return(indexValue); }
public override eeObject VisitFactorialExp([NotNull] EelooParser.FactorialExpContext ctx) { // add this to scope Interpreter.currentScope.scopeCtx = ctx; var num = Visit(ctx.exp()); if (num.type != eeObjectType.NUMBER) { throw new Exception(); } eeNumber fact = num.AsNumber().Factorial(); return(eeObject.newNumberObject(fact)); }
public override eeObject VisitFrom_loop([NotNull] EelooParser.From_loopContext ctx) { var scope = new Scope(Interpreter.currentScope, ctx); scope.ScopeThis(); eeObject start = Visit(ctx.exp(0)), stop = Visit(ctx.exp(1)); eeNumber step = ctx.RANGE_2() != null ? Visit(ctx.exp(2)).AsNumber() : 1; // If range is reversed if (stop.IsLessThan(start)) { // Switch start and stop var b = start; start = stop; stop = b; // Reverse step step *= new eeNumber(1); } var iterVar = ctx.IDENTIFIER().GetText(); for ( eeObject iter = start; iter.IsLessThanOrEqualTo(stop); iter.value = (iter.AsNumber() + step) ) { scope.assignVar(iterVar, iter); var codeblock = Visit(ctx.lines()); if (codeblock != null) { Scope.unScope(scope); return(codeblock); } } Scope.unScope(scope); return(eeObject.None); }
public override eeObject VisitRangeExp([NotNull] EelooParser.RangeExpContext ctx) { // add this to scope Interpreter.currentScope.scopeCtx = ctx; EelooParser.ExpContext[] exps = ctx.exp(); eeObject exp1 = Visit(exps[0]), exp2 = Visit(exps[1]); if (exp1.AsNumber() == null || exp2.AsNumber() == null) { throw new Exception("TO DO"); } eeNumber start = exp1.AsNumber(), stop = exp2.AsNumber(); ICollection <eeObject> rangeObj; if (exps.Length == 2) // only two numbers provided, assume step is 1 { rangeObj = RangeGenerator.Generate(start, stop, eeNumber.ONE); } else { rangeObj = RangeGenerator.Generate(start, stop, Visit(exps[2]).AsNumber()); } eeObject exprList = new eeObject(rangeObj) { type = eeObjectType.internal_EXPRLIST }; return(eeObject.newListObject(exprList)); }
public static eeObject Multiply(eeObject exp1, eeObject exp2) { if (! ((exp1.type == eeObjectType.STRING && exp2.type == eeObjectType.NUMBER) || (exp1.type == eeObjectType.NUMBER && exp2.type == eeObjectType.STRING)) ) { throw new Exception("String multiplication factors must be of type string and number."); } // Figure out which one is a string and which one is a num string str = exp1.type == eeObjectType.NUMBER ? exp2.AsString() : exp1.AsString(); eeNumber num = exp1.type == eeObjectType.NUMBER ? exp1.AsNumber() : exp2.AsNumber(); // Copy string n times string concat = ""; for (eeNumber i = new eeNumber(0); i < num; i += new eeNumber(1)) { concat += str; } return(eeObject.newStringObject(concat)); }
public DivisionByZeroError(eeNumber num1) : base("DivisionByZeroError", $"Cannot divide number {num1} by 0.") { }
// Reads the value of this eeObject, cross references the type and the modifier, and returns true if all checks out properly public bool Verify() { if (this.modifier == null) { return(true); } bool valid = true; switch (this.type) { case eeObjectType.NUMBER: eeNumber num = AsNumber(); switch (modifier) { case "negative": if (num > eeNumber.ZERO) { valid = false; } break; case "positive": if (num < eeNumber.ZERO) { valid = false; } break; case "even": if (num % eeNumber.TWO != eeNumber.ZERO) { valid = false; } break; case "odd": if (num % eeNumber.TWO != eeNumber.ONE) { valid = false; } break; default: throw new Exception("Unknown modifier: " + modifier); } break; case eeObjectType.LIST: var list = this.AsList(); switch (modifier) { case "unique": var disct = list.Select(s => s.value).Distinct(); if (disct.Count() != list.Count()) { valid = false; } break; default: throw new Exception("Unknown modifier: " + modifier); } break; } if (valid) { return(valid); } else { throw new Exception($"Constraint '{modifier}' violated with value of {this.ToPrintableString()}"); } }
public override eeObject VisitArrayIndex([NotNull] EelooParser.ArrayIndexContext ctx) { // add this to scope Interpreter.currentScope.scopeCtx = ctx; // Get the name of the array variable string iden = ctx.var().GetText(); // Get the value var variableVal = Interpreter.currentScope.resolveVar(iden); // if it doesnt exist if (variableVal == null) { return(null); } // Make sure it's an array or string variable else if (variableVal.type != eeObjectType.LIST && variableVal.type != eeObjectType.STRING) { throw new Exception($"{iden} is not a string or array."); } // Bring it into a C# List<eeObject> type List <eeObject> array = variableVal.AsList(); // Evaluate the index var index = Visit(ctx.exp()); // First, Make sure the requested index is a number if (index.type != eeObjectType.NUMBER) { throw new Exception("TO DO: Index is not a number"); } // workaround for now to get eeNumbers to work with c#'s arrays eeNumber indexValue_ee = index.AsNumber(); int indexValue; for (indexValue = 0; new eeNumber(indexValue) < indexValue_ee; ++indexValue) { ; } bool reversed = false; // If the index is a negative number // -1 will be last element, -2 second last elem, -0 will be first element though if (indexValue < 0) { indexValue = Math.Abs(indexValue); indexValue--; // Decrement to conform to regular indexes array.Reverse(); reversed = true; } // Then make sure the index is in range if (!(indexValue >= 0 && indexValue < array.Count)) { throw new Exception("TO DO: Index out of range"); } // return the value at the index var valAtIdx = array[indexValue]; // Reverse the array back to its orignal state if it was reversed if (reversed) { array.Reverse(); } return(valAtIdx); }