public void Parse(ref string[] program) { string token = ParseUtils.GetToken(ref program); WooScript._Log.AddMsg("Found function, target \"" + token + "\""); WooScript._Log.Indent(); if (WooScript.IsFloatVariable(token)) { _ReturnType = VarType.varFloat; _Var = token; } else if (WooScript.IsVecVariable(token)) { _ReturnType = VarType.varVector; _Var = token; } else { throw new ParseException("Expected \"" + token + "\" to be a float or vector variable"); } string assignOp = ParseUtils.GetToken(ref program); _AssignOp = WooScript.GetAssignOp(assignOp); _Expression = ExpressionBuilder.Parse(ref program); if (_ReturnType == VarType.varVector && (_Expression.GetExpressionType() != VarType.varVector)) throw new ParseException("Target token is \"" + token + "\" which is a vector, expression isn't..."); if (_ReturnType == VarType.varFloat && (_Expression.GetExpressionType() != VarType.varFloat)) throw new ParseException("Target token is \"" + token + "\" which is a float, expression isn't..."); }
private static string OpName(AssignOp op) { switch (op) { case AssignOp.ASSIGN: return("="); case AssignOp.ADD: return("+="); case AssignOp.SUB: return("-="); case AssignOp.MUL: return("*="); case AssignOp.DIV: return("/="); case AssignOp.MOD: return("%="); default: throw new ArgumentOutOfRangeException(nameof(op), op, null); } }
public void visit(AssignOp assignOp) { string name = assignOp.left.name; assignOp.right.accept(this); stack.pushGlobal(name, assignOp.right.output); }
public LValueAssign(AssignOp op, Expression lvalue, Expression value) { Operator = op; LValue = lvalue; Value = value; Line = lvalue.Line; Column = lvalue.Column; }
public void visit(AssignOp assignOp) { if (!scope.contains(assignOp.left.name)) { declareSymbol(assignOp.left, assignOp.type); } assignOp.right.accept(this); }
public static LinkedListNode <Lexeme> TryParse(LinkedListNode <Lexeme> lexemes, out AssignStmt resultNode, bool needSC = true) { resultNode = null; var nextLexeme = Var.TryParse(lexemes, out Var lhs); if (lhs == null) { return(lexemes); } AssignOp op = AssignOp.ASSIGN; if (nextLexeme.Value.Type == LT.OP_ADD || nextLexeme.Value.Type == LT.OP_SUB || nextLexeme.Value.Type == LT.OP_MUL || nextLexeme.Value.Type == LT.OP_DIV || nextLexeme.Value.Type == LT.OP_MOD) { op = TypeToOp(nextLexeme.Value.Type); nextLexeme = nextLexeme.Next; } if (nextLexeme.Value.Type != LT.OP_ASSIGN) { return(lexemes); } Lexeme token = nextLexeme.Value; nextLexeme = Expr.TryParse(nextLexeme.Next, out Expr rhs); if (rhs == null) { throw new Exception($"Unrecognized right hand member of operator '{OpName(op)}' at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } if (needSC) { if (nextLexeme.Value.Type != LT.OP_SC) { throw new Exception($"Missing semicolon after statement at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; } resultNode = new AssignStmt { LHS = lhs, RHS = rhs, Op = op, Token = token }; return(nextLexeme); }
private string GetValue(AssignOp op) { switch (op) { case AssignOp.Assign: return("="); case AssignOp.AddAssign: return("+="); case AssignOp.SubAssign: return("-="); case AssignOp.MulAssign: return("*="); case AssignOp.DivAssign: return("/="); } return(null); }
public void Parse(ref string[] program) { string token = ParseUtils.GetToken(ref program); WooScript._Log.AddMsg("Found function, target \"" + token + "\""); WooScript._Log.Indent(); if (WooScript.IsFloatVariable(token)) { _ReturnType = VarType.varFloat; _Var = token; } else if (WooScript.IsVecVariable(token)) { _ReturnType = VarType.varVector; _Var = token; } else { throw new ParseException("Expected \"" + token + "\" to be a float or vector variable"); } string assignOp = ParseUtils.GetToken(ref program); _AssignOp = WooScript.GetAssignOp(assignOp); _Expression = ExpressionBuilder.Parse(ref program); if (_ReturnType == VarType.varVector && (_Expression.GetExpressionType() != VarType.varVector)) { throw new ParseException("Target token is \"" + token + "\" which is a vector, expression isn't..."); } if (_ReturnType == VarType.varFloat && (_Expression.GetExpressionType() != VarType.varFloat)) { throw new ParseException("Target token is \"" + token + "\" which is a float, expression isn't..."); } }
/// <summary> /// Optimization #6: /// Constant substitution /// /// TODO: This method has some inconsistencies when setting the offset with the new memory operations. /// For some memory operations, I'm using "new {Op}(ptr + {op}.Offset)" /// and for others I'm just using "new {Op}({op}.Offset)". /// I'm pretty sure this inconsistency is causing some problems. /// </summary> /// <param name="operations"></param> private bool SubstituteConstants(ref DILOperationSet operations) { if (WereConstantsSubstituted) { return(false); } var ptr = 0; var arr = operations.ToArray(); var didAnysubstitutions = false; for (int i = 0; i < arr.Length; i++) { var operation = arr[i]; if (operation is AdditionMemoryOp) { var add = (AdditionMemoryOp)operation; if (add.Constant == null) { arr[i] = new AdditionMemoryOp(ptr + add.Offset, add.Scalar, new ConstantValue(ptr + add.Offset)); didAnysubstitutions = true; } } else if (operation is MultiplicationMemoryOp) { var mul = (MultiplicationMemoryOp)operation; if (mul.Constant == null) { arr[i] = new MultiplicationMemoryOp(ptr + mul.Offset, mul.Scalar, new ConstantValue(ptr + mul.Offset), new ConstantValue(ptr)); } } else if (operation is AssignOp) { var ass = arr[i] as AssignOp; if (ass.Constant == null) { arr[i] = new AssignOp(ptr + ass.Offset, ass.Value, new ConstantValue(ptr + ass.Offset)); didAnysubstitutions = true; } } else if (operation is PtrOp) { arr[i] = null; // if we're using constants, then we don't need pointer movements var ptrOp = (PtrOp)operation; ptr += ptrOp.Delta; //didAnysubstitutions = true; } else if (operation is WriteOp) { var write = ((WriteOp)arr[i]); if (write.Constant == null) { arr[i] = new WriteOp(write.Offset, write.Repeated, new ConstantValue(ptr)); didAnysubstitutions = true; } } else if (operation is ReadOp) { var read = ((ReadOp)arr[i]); if (read.Constant == null) { arr[i] = new ReadOp(read.Offset, read.Repeated, new ConstantValue(ptr)); didAnysubstitutions = true; } } } var list = arr.ToList(); list.RemoveAll(l => l == null); operations = new DILOperationSet(list); operations.WereConstantsSubstituted = true; return(didAnysubstitutions); }