package parser import ( "math" "sfdl/scanner" "sfdl/semantices" ) var ( Parameter float64 // T OriginX, OriginY float64 ScaleX, ScaleY float64 = 1, 1 RotAngle float64 // 弧度 ) func ResetState() { Parameter = 0 OriginX, OriginY = 0, 0 ScaleX, ScaleY = 1, 1 RotAngle = 0 } func evalExpr(root *ExprNode) float64 { if root == nil { return 0 } switch root.Op { case scanner.PLUS: return evalExpr(root.Left) + evalExpr(root.Right) case scanner.MINUS: return evalExpr(root.Left) - evalExpr(root.Right) case scanner.MUL: return evalExpr(root.Left) * evalExpr(root.Right) case scanner.DIV: return evalExpr(root.Left) / evalExpr(root.Right) case scanner.POWER: return math.Pow(evalExpr(root.Left), evalExpr(root.Right)) case scanner.FUNC: return root.Func(evalExpr(root.Left)) case scanner.CONST_ID: return root.Value case scanner.T: return Parameter default: return 0 } } func calcCoord(xExpr, yExpr *ExprNode) (float64, float64) { x := evalExpr(xExpr) y := evalExpr(yExpr) // scale x *= ScaleX y *= ScaleY // rotate tx := x*math.Cos(RotAngle) + y*math.Sin(RotAngle) ty := y*math.Cos(RotAngle) - x*math.Sin(RotAngle) x, y = tx, ty // translate x += OriginX y += OriginY return x, y } // ORIGIN IS (x, y) func originStatement(xExpr, yExpr *ExprNode) { OriginX = evalExpr(xExpr) OriginY = evalExpr(yExpr) } // SCALE IS (sx, sy) func scaleStatement(xExpr, yExpr *ExprNode) { ScaleX = evalExpr(xExpr) ScaleY = evalExpr(yExpr) } // ROT IS angle func rotStatement(angleExpr *ExprNode) { RotAngle = evalExpr(angleExpr) } // FOR T FROM start TO end STEP step DRAW (xExpr, yExpr) func forStatement(startExpr, endExpr, stepExpr, xExpr, yExpr *ExprNode) { start := evalExpr(startExpr) end := evalExpr(endExpr) step := evalExpr(stepExpr) if step <= 1e-9 { return } for Parameter = start; Parameter <= end; Parameter += step { x, y := calcCoord(xExpr, yExpr) semantices.DrawPixel(int(math.Round(x)), int(math.Round(y))) } }