public static void Main(String[] args) { //multiple ways to construct a BigFloat BigFloat bigfloat1 = new BigFloat(1234567); BigFloat bigfloat2 = new BigFloat("1234567"); BigFloat bigfloat3 = new BigFloat(1234567.0); BigFloat bigfloat4 = BigFloat.Parse("1234567.123"); Console.WriteLine("(1234567 * 12)^2 - 15 = \n"); Console.WriteLine("Arithmetic: " + (Math.Pow(1234567 * 12, 2) - 15)); //non-static methods Console.WriteLine("BigFloat w/ non-static: " + bigfloat1.Multiply(12).Pow(2).Subtract(15)); //static methods bigfloat2 = BigFloat.Multiply(bigfloat2, 12); bigfloat2 = BigFloat.Pow(bigfloat2, 2); bigfloat2 = BigFloat.Subtract(bigfloat2, new BigInteger(15)); Console.WriteLine("BigFloat w/ static : " + bigfloat2); //operators Console.WriteLine("BigFloat w/ operators : " + (((bigfloat3 * 12) ^ 2) - 15)); Console.WriteLine(); //additional methods Console.WriteLine("Round(1234567.1234) = " + BigFloat.Round(bigfloat4)); Console.WriteLine("Ceil(1234567.1234) = " + BigFloat.Ceil(bigfloat4)); Console.WriteLine("Floor(1234567.1234) = " + BigFloat.Floor(bigfloat4)); Console.WriteLine("Inverse(1234567.1234) = " + BigFloat.Inverse(bigfloat4).ToString(20)); Console.WriteLine("Sqrt(1234567.1234) = " + BigFloat.Sqrt(bigfloat4)); Console.WriteLine("log10(1234567.1234) = " + BigFloat.Log10(bigfloat4)); //large numbers BigFloat pi = new BigFloat("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949"); Console.WriteLine("\nPi to a really long decimal place:"); Console.WriteLine(pi.ToString(200)); Console.WriteLine("\nTau (2*PI): "); Console.WriteLine((pi * 2).ToString(200)); Console.Read(); }
//Float. public static AlgoValue ConvertFlt(ParserRuleContext context, params AlgoValue[] args) { //Is it a string? if (args[0].Type == AlgoValueType.String) { //Return a parsed bigfloat. return(new AlgoValue() { Type = AlgoValueType.Float, Value = BigFloat.Parse((string)args[0].Value) }); } //Nah, then just cast. return(AlgoOperators.ConvertType(context, args[0], AlgoValueType.Float)); }
//Check if a string is a valid float. public static AlgoValue IsFloat(ParserRuleContext context, params AlgoValue[] args) { //Check input type. if (args[0].Type == AlgoValueType.Float) { return(AlgoValue.True); } if (args[0].Type != AlgoValueType.String) { return(AlgoValue.False); } //It's a string, check if it can be parsed to an integer. try { BigFloat b = BigFloat.Parse((string)args[0].Value); return(AlgoValue.True); } catch { return(AlgoValue.False); } }
//When a single value is visited in Algo. public override object VisitValue([NotNull] algoParser.ValueContext context) { //Check what type the value is. if (context.INTEGER() != null) { //INTEGER return(new AlgoValue() { Type = AlgoValueType.Integer, Value = BigInteger.Parse(context.INTEGER().GetText()), }); } else if (context.FLOAT() != null) { //FLOAT return(new AlgoValue() { Type = AlgoValueType.Float, Value = BigFloat.Parse(context.FLOAT().GetText()), }); } else if (context.STRING() != null) { //STRING return(new AlgoValue() { Type = AlgoValueType.String, Value = context.STRING().GetText().Substring(1, context.STRING().GetText().Length - 2) //text escape codes .Replace("\\n", "\n") .Replace("\\t", "\t") .Replace("\\r", "\r") .Replace("\\q", "\"") }); } else if (context.RATIONAL() != null) { //RATIONAL //Get the two integer halves from the rational. string[] halves = context.RATIONAL().GetText().Split('/'); string numerator = halves[0]; string denominator = halves[1]; return(new AlgoValue() { Type = AlgoValueType.Rational, Value = new BigRational(BigInteger.Zero, new Fraction(BigInteger.Parse(numerator), BigInteger.Parse(denominator))), }); } else if (context.BOOLEAN() != null) { //BOOLEAN return(new AlgoValue() { Type = AlgoValueType.Boolean, Value = (context.BOOLEAN().GetText() == "true"), }); } else if (context.HEX() != null) { //BYTES return(new AlgoValue() { Type = AlgoValueType.Bytes, Value = context.HEX().GetText().ToByteArray() }); } else if (context.NULL() != null) { //NULL VALUE return(new AlgoValue() { Type = AlgoValueType.Null, Value = null, }); } else if (context.IDENTIFIER() != null) { //VARIABLE/OBJECT return(Particles.ParseParticleBlock(this, context, context.IDENTIFIER(), context.particle())); } else if (context.stat_functionCall() != null) { //FUNCTION CALL AlgoValue value = (AlgoValue)VisitStat_functionCall(context.stat_functionCall()); if (value != null) { return(value); } else { //Return a null value. return(new AlgoValue() { Type = AlgoValueType.Null, Value = null, }); } } else if (context.array() != null) { //LIST. //Evaluate all list items as expressions. List <AlgoValue> list = new List <AlgoValue>(); foreach (var item in context.array().value()) { list.Add((AlgoValue)VisitValue(item)); } //Return as a single value. return(new AlgoValue() { Type = AlgoValueType.List, Value = list }); } else if (context.@object() != null) { //OBJECT DEFINITION //Create a new object. AlgoObject toReturn = new AlgoObject(); //Anything to enumerate? if (context.@object().obj_child_definitions() == null) { //Nope. return(new AlgoValue() { Type = AlgoValueType.Object, Value = toReturn }); } //Enumerate through all the define statements and evaluate their values. foreach (var value in context.@object().obj_child_definitions().obj_vardefine()) { //Check if the variable already exists. if (toReturn.ObjectScopes.VariableExists(value.IDENTIFIER().GetText())) { Error.Fatal(context, "The variable with name '" + value.IDENTIFIER().GetText() + "' is defined twice or more in an object."); return(null); } //Evaluate the value on the right. AlgoValue evaluated = (AlgoValue)VisitExpr(value.expr()); //Add the variable to scope. toReturn.ObjectScopes.AddVariable(value.IDENTIFIER().GetText(), evaluated); } //Enumerate through all functions and define them. foreach (var value in context.@object().obj_child_definitions().obj_funcdefine()) { //Check if the variable already exists. if (toReturn.ObjectScopes.VariableExists(value.IDENTIFIER().GetText())) { Error.Fatal(context, "The variable with name '" + value.IDENTIFIER().GetText() + "' is defined twice or more in an object."); return(null); } //Create a list of parameters. List <string> params_ = new List <string>(); if (value.abstract_params() != null) { foreach (var param in value.abstract_params().IDENTIFIER()) { //Check if param already exists. if (params_.Contains(param.GetText())) { Error.Fatal(context, "The parameter with name '" + param.GetText() + "' is already defined in the function."); return(null); } params_.Add(param.GetText()); } } //Create a function, push. AlgoFunction func = new AlgoFunction(value.statement().ToList(), params_, value.IDENTIFIER().GetText()); AlgoValue funcValue = new AlgoValue() { Type = AlgoValueType.Function, Value = func, }; toReturn.ObjectScopes.AddVariable(value.IDENTIFIER().GetText(), funcValue); } //Enumerate all external functions defined. foreach (var ext in context.@object().obj_child_definitions().obj_externdefine()) { //Get the value of the function. var loadFuncStat = ext.stat_loadFuncExt(); AlgoValue func = Plugins.GetEmulatedFuncValue(loadFuncStat); //Check if a variable with this name already exists. if (toReturn.ObjectScopes.VariableExists(loadFuncStat.IDENTIFIER()[0].GetText())) { Error.Fatal(context, "A variable with the name '" + loadFuncStat.IDENTIFIER()[0].GetText() + "' already exists in this object. Cannot duplicate."); return(null); } //Add that function to the return object. toReturn.ObjectScopes.AddVariable(loadFuncStat.IDENTIFIER()[0].GetText(), func); } //Return the object. return(new AlgoValue() { Type = AlgoValueType.Object, Value = toReturn }); } else { //No proper detected value type. Error.Fatal(context, "Unknown or invalid type given for value."); return(new AlgoValue() { Type = AlgoValueType.Null, Value = null }); } }
//Turns a JObject deserialized object into an AlgoValue. private static AlgoValue ParseJsonObject(ParserRuleContext context, dynamic deserialized) { //Enumerate over properties. AlgoObject obj = new AlgoObject(); foreach (JProperty token in ((JObject)deserialized).Properties()) { switch (token.Value.Type) { //JSON Integer Representation case JTokenType.Integer: obj.ObjectScopes.AddVariable(token.Name, new AlgoValue() { Type = AlgoValueType.Integer, Value = BigInteger.Parse(token.Value.ToString()) }); break; //JSON String Representation case JTokenType.String: obj.ObjectScopes.AddVariable(token.Name, new AlgoValue() { Type = AlgoValueType.String, Value = token.Value.ToString() }); break; //JSON Array Representation case JTokenType.Array: obj.ObjectScopes.AddVariable(token.Name, ParseJsonArray(context, (JArray)token.Value)); break; //JSON Boolean Representation case JTokenType.Boolean: obj.ObjectScopes.AddVariable(token.Name, new AlgoValue() { Type = AlgoValueType.Boolean, Value = bool.Parse(token.Value.ToString()) }); break; //JSON Float Representation case JTokenType.Float: obj.ObjectScopes.AddVariable(token.Name, new AlgoValue() { Type = AlgoValueType.Float, Value = BigFloat.Parse(token.Value.ToString()) }); break; //JSON Null Representation case JTokenType.Null: obj.ObjectScopes.AddVariable(token.Name, AlgoValue.Null); break; //JSON Object Representation case JTokenType.Object: obj.ObjectScopes.AddVariable(token.Name, ParseJsonObject(context, (JObject)token.Value)); break; default: Error.Fatal(context, "Invalid type '" + token.Value.Type.ToString() + "' to parse from JSON."); return(null); } } //Return the finished object. return(new AlgoValue() { Type = AlgoValueType.Object, Value = obj }); }
//Turns a JArray deserialized object into an AlgoValue. private static AlgoValue ParseJsonArray(ParserRuleContext context, dynamic deserialized) { //Enumerate over values. List <AlgoValue> list = new List <AlgoValue>(); foreach (JToken token in ((JArray)deserialized).Children()) { switch (token.Type) { //Same parsing as below, but for a list. case JTokenType.Integer: list.Add(new AlgoValue() { Type = AlgoValueType.Integer, Value = BigInteger.Parse(token.ToString()) }); break; case JTokenType.String: list.Add(new AlgoValue() { Type = AlgoValueType.String, Value = token.ToString() }); break; case JTokenType.Array: list.Add(ParseJsonArray(context, (JArray)token)); break; case JTokenType.Boolean: list.Add(new AlgoValue() { Type = AlgoValueType.Boolean, Value = bool.Parse(token.ToString()) }); break; case JTokenType.Float: list.Add(new AlgoValue() { Type = AlgoValueType.Float, Value = BigFloat.Parse(token.ToString()) }); break; case JTokenType.Null: list.Add(AlgoValue.Null); break; case JTokenType.Object: list.Add(ParseJsonObject(context, (JObject)token)); break; } } return(new AlgoValue() { Type = AlgoValueType.List, Value = list }); }