//When an expression is parsed in Algo. public override object VisitExpr([NotNull] algoParser.ExprContext context) { //Is it an addition? if (context.ADD_OP() != null) { //Yes. Evaluate the left hand expression. AlgoValue left = (AlgoValue)VisitExpr(context.expr()); //Evaluate the right hand term. AlgoValue right = (AlgoValue)VisitTerm(context.term()); //Perform an add operation, based on type. return(AlgoOperators.Add(context, left, right)); } else if (context.TAKE_OP() != null) { //Take operation. //Evaluate the left hand expression. AlgoValue left = (AlgoValue)VisitExpr(context.expr()); //Evaluate the right hand term. AlgoValue right = (AlgoValue)VisitTerm(context.term()); //Perform a take operation, based on type. return(AlgoOperators.Sub(context, left, right)); } else { //No, just a term, evaluate. return((AlgoValue)VisitTerm(context.term())); } }
//When a variable is modified using a postfix operator. public override object VisitStat_setvar_postfix([NotNull] algoParser.Stat_setvar_postfixContext context) { //Get variable name. AlgoValue oldValue = Particles.ParseParticleBlock(this, context, context.IDENTIFIER(), context.particle()); if (oldValue == null) { Error.Fatal(context, "No value returned to modify with operator."); return(null); } //Switch on the operator type. int toAdd = 0; if (context.postfix_op().ADD_PFOP() != null) { //Increment. toAdd = 1; } else { //Decrement. toAdd = -1; } //Apply the operator. AlgoValue newValue = null; switch (oldValue.Type) { case AlgoValueType.Integer: case AlgoValueType.Float: case AlgoValueType.Rational: newValue = AlgoOperators.Add(context, oldValue, new AlgoValue() { Type = AlgoValueType.Integer, Value = new BigInteger(toAdd) }); break; default: Error.Fatal(context, "Cannot increment a variable of type " + oldValue.Type.ToString() + "."); return(null); } //Set the variable value. oldValue.Value = newValue.Value; oldValue.Type = newValue.Type; return(null); }
//When a variable value is changed by a self modifying operator. public override object VisitStat_setvar_op([NotNull] algoParser.Stat_setvar_opContext context) { //Get variable reference. AlgoValue oldValue = Particles.ParseParticleBlock(this, context, context.IDENTIFIER(), context.particle()); if (oldValue == null) { Error.Fatal(context, "No value returned to modify with operator."); return(null); } //Does, evaluate the expression to set the value. AlgoValue value = (AlgoValue)VisitExpr(context.expr()); //Switching on selfmod value. AlgoValue newValue; if (context.selfmod_op().ADDFROM_OP() != null) { //Attempt to add. newValue = AlgoOperators.Add(context, oldValue, value); } else if (context.selfmod_op().DIVFROM_OP() != null) { //Attempt to divide. newValue = AlgoOperators.Div(context, oldValue, value); } else if (context.selfmod_op().MULFROM_OP() != null) { //Attempt to multiply. newValue = AlgoOperators.Mul(context, oldValue, value); } else if (context.selfmod_op().TAKEFROM_OP() != null) { //Attempt to subtract. newValue = AlgoOperators.Sub(context, oldValue, value); } else { //Invalid operator type, oopsie! Implemented in parser but not here. Error.Fatal(context, "Invalid operator given for self modifying variable, implemented in parser but not in interpreter."); return(null); } //Set the value of the variable. oldValue.Value = newValue.Value; oldValue.Type = newValue.Type; return(null); }