@@ -86,12 +86,15 @@ func DefaultBuiltins(rt Runtime) Builtins {
8686 "line" : xyBuiltin ("line" , rt .Line ),
8787 "rect" : xyBuiltin ("rect" , rt .Rect ),
8888 "circle" : numBuiltin ("circle" , rt .Circle ),
89+
8990 "width" : numBuiltin ("width" , rt .Width ),
9091 "color" : stringBuiltin ("color" , rt .Color ),
9192 "colour" : stringBuiltin ("colour" , rt .Color ),
9293 "clear" : {Func : clearFunc (rt .Clear ), Decl : clearDecl },
9394
94- "poly" : {Func : polyFunc (rt .Poly ), Decl : polyDecl },
95+ "poly" : {Func : polyFunc (rt .Poly ), Decl : polyDecl },
96+ "ellipse" : {Func : ellipseFunc (rt .Ellipse ), Decl : ellipseDecl },
97+ "curve" : {Func : curveFunc (rt .Curve ), Decl : curveDecl },
9598
9699 "stroke" : stringBuiltin ("stroke" , rt .Stroke ),
97100 "fill" : stringBuiltin ("fill" , rt .Fill ),
@@ -152,6 +155,8 @@ type GraphicsRuntime interface {
152155
153156 // advanced graphics functions
154157 Poly (vertices [][]float64 )
158+ Ellipse (x , y , radiusX , radiusY , rotation , startAngle , endAngle float64 )
159+ Curve (sements [][]float64 )
155160 Stroke (s string )
156161 Fill (s string )
157162 Dash (segments []float64 )
@@ -189,6 +194,7 @@ func (rt *UnimplementedRuntime) Width(w float64) { rt.Unimplemented("w
189194func (rt * UnimplementedRuntime ) Color (s string ) { rt .Unimplemented ("color" ) }
190195func (rt * UnimplementedRuntime ) Clear (color string ) { rt .Unimplemented ("clear" ) }
191196func (rt * UnimplementedRuntime ) Poly (vertices [][]float64 ) { rt .Unimplemented ("poly" ) }
197+ func (rt * UnimplementedRuntime ) Curve (sements [][]float64 ) { rt .Unimplemented ("curve" ) }
192198func (rt * UnimplementedRuntime ) Stroke (s string ) { rt .Unimplemented ("stroke" ) }
193199func (rt * UnimplementedRuntime ) Fill (s string ) { rt .Unimplemented ("fill" ) }
194200func (rt * UnimplementedRuntime ) Dash (segments []float64 ) { rt .Unimplemented ("dash" ) }
@@ -197,6 +203,9 @@ func (rt *UnimplementedRuntime) Text(s string) { rt.Unimplemented("t
197203func (rt * UnimplementedRuntime ) Textsize (size float64 ) { rt .Unimplemented ("textsize" ) }
198204func (rt * UnimplementedRuntime ) Font (s string ) { rt .Unimplemented ("font" ) }
199205func (rt * UnimplementedRuntime ) Fontfamily (s string ) { rt .Unimplemented ("fontfamily" ) }
206+ func (rt * UnimplementedRuntime ) Ellipse (x , y , rX , rY , rotation , startAngle , endAngle float64 ) {
207+ rt .Unimplemented ("ellipse" )
208+ }
200209
201210var readDecl = & parser.FuncDeclStmt {
202211 Name : "read" ,
@@ -607,6 +616,65 @@ func polyFunc(polyFn func([][]float64)) BuiltinFunc {
607616 }
608617}
609618
619+ var ellipseDecl = & parser.FuncDeclStmt {
620+ Name : "ellipse" ,
621+ VariadicParam : & parser.Var {Name : "n" , T : parser .NUM_TYPE },
622+ ReturnType : parser .NONE_TYPE ,
623+ }
624+
625+ func ellipseFunc (ellipseFn func (x , y , radiusX , radiusY , rotation , startAngle , endAngle float64 )) BuiltinFunc {
626+ return func (_ * scope , args []Value ) (Value , error ) {
627+ argLen := len (args )
628+ if argLen < 3 || argLen == 6 || argLen > 7 {
629+ return nil , fmt .Errorf ("%w: 'ellipse' requires 3,4,5,7 or arguments, found %d" , ErrBadArguments , argLen )
630+ }
631+ x := args [0 ].(* Num ).Val
632+ y := args [1 ].(* Num ).Val
633+ radiusX := args [2 ].(* Num ).Val
634+ radiusY := radiusX
635+ rotation := 0.0
636+ startAngle := 0.0
637+ endAngle := 360.0
638+ if argLen > 3 {
639+ radiusY = args [3 ].(* Num ).Val
640+ }
641+ if argLen > 4 {
642+ rotation = args [4 ].(* Num ).Val
643+ }
644+ if argLen > 6 {
645+ startAngle = args [5 ].(* Num ).Val
646+ endAngle = args [6 ].(* Num ).Val
647+ }
648+ ellipseFn (x , y , radiusX , radiusY , rotation , startAngle , endAngle )
649+ return nil , nil
650+ }
651+ }
652+
653+ var curveDecl = & parser.FuncDeclStmt {
654+ Name : "curve" ,
655+ VariadicParam : & parser.Var {Name : "n" , T : numArrayType },
656+ ReturnType : parser .NONE_TYPE ,
657+ }
658+
659+ func curveFunc (curveFn func ([][]float64 )) BuiltinFunc {
660+ return func (_ * scope , args []Value ) (Value , error ) {
661+ segments := make ([][]float64 , len (args ))
662+ for i , arg := range args {
663+ vertex := arg .(* Array )
664+ elements := * vertex .Elements
665+ if len (elements ) < 2 || len (elements ) == 3 || len (elements ) > 6 {
666+ return nil , fmt .Errorf ("%w: 'curve' argument %d has %d elements, expected 2, 4, 5 or 6" , ErrBadArguments , i + 1 , len (elements ))
667+ }
668+ segments [i ] = make ([]float64 , len (elements ))
669+ for j , val := range elements {
670+ segments [i ][j ] = val .(* Num ).Val
671+ }
672+ }
673+ curveFn (segments )
674+ return nil , nil
675+ }
676+ }
677+
610678var dashDecl = & parser.FuncDeclStmt {
611679 Name : "dash" ,
612680 VariadicParam : & parser.Var {Name : "segments" , T : parser .NUM_TYPE },
0 commit comments