diff --git a/src/ast.fs b/src/ast.fs index 4aef9518..a3d46782 100644 --- a/src/ast.fs +++ b/src/ast.fs @@ -43,7 +43,7 @@ let stringToJumpKeyword = function type Expr = | Int of int * string - | Float of float * string + | Float of decimal * string | Var of Ident | Op of string | FunCall of Expr * Expr list diff --git a/src/parse.fs b/src/parse.fs index 686d3cf8..845b810a 100644 --- a/src/parse.fs +++ b/src/parse.fs @@ -54,7 +54,7 @@ module private ParseImpl = let conv s = let ok, res = System.Int32.TryParse(s : string) if ok then Ast.Int (res, "") - else Ast.Float (try float s, "" with _ -> failwith ("invalid number: " + s)) + else Ast.Float (try decimal s, "" with _ -> failwith ("invalid number: " + s)) regex r .>> ws |>> conv let anyNumber = diff --git a/src/printer.fs b/src/printer.fs index 7fe78ec1..c36df0c8 100644 --- a/src/printer.fs +++ b/src/printer.fs @@ -3,6 +3,7 @@ open System open Ast open Options.Globals +open System.Text.RegularExpressions module private PrinterImpl = @@ -46,13 +47,17 @@ module private PrinterImpl = List.map toS li |> String.concat "," let floatToS f = - let si = if f < 0. then "-" else "" - let test = out "%g" (abs f) - // display "3." instead of "3" - if fst (System.Int32.TryParse test) then (out "%g." f) - // display ".5" instead of "0.5" - else if test.[0] = '0' then si + (test.[1..]) - else si + test + let si = if f < 0.M then "-" else "" + let f = abs (float f) + let str = f.ToString("g", System.Globalization.CultureInfo.InvariantCulture) + let str = if str.EndsWith(".0") then str.[0..str.Length-2] else str + + if Regex.Match(str, "^\\d+$").Success then + si + str + "." // display "3." instead of "3" + elif str.[0] = '0' && str.Length > 2 then + si + (str.[1..]) // display ".5" instead of "0.5" + else + si + str let rec exprToS exp = exprToSLevel 0 exp diff --git a/src/rewriter.fs b/src/rewriter.fs index 45cde208..14e70fa5 100644 --- a/src/rewriter.fs +++ b/src/rewriter.fs @@ -71,7 +71,7 @@ let rec private simplifyExpr env = function | FunCall(Op ",", [e1; FunCall(Op ",", [e2; e3])]) -> FunCall(Op ",", [simplifyExpr env (FunCall(Op ",", [e1; e2])); e3]) - | FunCall(Op "-", [x; Float (f, s)]) when f < 0. -> + | FunCall(Op "-", [x; Float (f, s)]) when f < 0.M -> FunCall(Op "+", [x; Float (-f, s)]) |> simplifyExpr env | FunCall(Op "-", [x; Int (i, s)]) when i < 0 -> FunCall(Op "+", [x; Int (-i, s)]) |> simplifyExpr env @@ -92,15 +92,15 @@ let rec private simplifyExpr env = function | FunCall(Op "!=", [Float (i1,_); Float (i2,_)]) -> bool(i1 <> i2) // Stupid simplifications (they can be useful to simplify rewritten code) - | FunCall(Op "/", [e; Float (1.,_)]) -> e - | FunCall(Op "*", [e; Float (1.,_)]) -> e - | FunCall(Op "*", [Float (1.,_); e]) -> e - | FunCall(Op "*", [_; Float (0.,_) as e]) -> e - | FunCall(Op "*", [Float (0.,_) as e; _]) -> e - | FunCall(Op "+", [e; Float (0.,_)]) -> e - | FunCall(Op "+", [Float (0.,_); e]) -> e - | FunCall(Op "-", [e; Float (0.,_)]) -> e - | FunCall(Op "-", [Float (0.,_); e]) -> FunCall(Op "-", [e]) + | FunCall(Op "/", [e; Float (1.M,_)]) -> e + | FunCall(Op "*", [e; Float (1.M,_)]) -> e + | FunCall(Op "*", [Float (1.M,_); e]) -> e + | FunCall(Op "*", [_; Float (0.M,_) as e]) -> e + | FunCall(Op "*", [Float (0.M,_) as e; _]) -> e + | FunCall(Op "+", [e; Float (0.M,_)]) -> e + | FunCall(Op "+", [Float (0.M,_); e]) -> e + | FunCall(Op "-", [e; Float (0.M,_)]) -> e + | FunCall(Op "-", [Float (0.M,_); e]) -> FunCall(Op "-", [e]) // No simplification when numbers have different suffixes | FunCall(_, [Int (_, su1); Int (_, su2)]) as e when su1 <> su2 -> e @@ -112,7 +112,7 @@ let rec private simplifyExpr env = function | FunCall(Op "/", [Int (i1, su); Int (i2, _)]) -> Int (i1 / i2, su) | FunCall(Op "%", [Int (i1, su); Int (i2, _)]) -> Int (i1 % i2, su) - | FunCall(Op "-", [Float (0.0,su)]) -> Float (0.0, su) + | FunCall(Op "-", [Float (0.M,su)]) -> Float (0.M, su) | FunCall(Op "-", [Float (f1,su)]) -> Float (-f1, su) | FunCall(Op "-", [Float (i1,su); Float (i2,_)]) -> Float (i1 - i2, su) | FunCall(Op "+", [Float (i1,su); Float (i2,_)]) -> Float (i1 + i2, su) @@ -123,12 +123,12 @@ let rec private simplifyExpr env = function else div // iq's smoothstep trick: http://www.pouet.net/topic.php?which=6751&page=1#c295695 - | FunCall(Var var, [Float (0.,_); Float (1.,_); _]) as e when var.Name = "smoothstep" -> e + | FunCall(Var var, [Float (0.M,_); Float (1.M,_); _]) as e when var.Name = "smoothstep" -> e | FunCall(Var var, [a; b; x]) when var.Name = "smoothstep" && options.smoothstepTrick -> let sub1 = FunCall(Op "-", [x; a]) let sub2 = FunCall(Op "-", [b; a]) let div = FunCall(Op "/", [sub1; sub2]) |> mapExpr env - FunCall(Var (Ident "smoothstep"), [Float (0.,""); Float (1.,""); div]) + FunCall(Var (Ident "smoothstep"), [Float (0.M,""); Float (1.M,""); div]) | Dot(e, field) when options.canonicalFieldNames <> "" -> Dot(e, renameField field) @@ -138,9 +138,9 @@ let rec private simplifyExpr env = function | _ -> e // pi is acos(-1), pi/2 is acos(0) - | Float(f, _) when f = 3.141592653589793 -> FunCall(Var (Ident "acos"), [Float (-1., "")]) - | Float(f, _) when f = 6.283185307179586 -> FunCall(Op "*", [Float (2., ""); FunCall(Var (Ident "acos"), [Float (-1., "")])]) - | Float(f, _) when f = 1.5707963267948966 -> FunCall(Var (Ident "acos"), [Float (0., "")]) + | Float(f, _) when float f = 3.141592653589793 -> FunCall(Var (Ident "acos"), [Float (-1.M, "")]) + | Float(f, _) when float f = 6.283185307179586 -> FunCall(Op "*", [Float (2.M, ""); FunCall(Var (Ident "acos"), [Float (-1.M, "")])]) + | Float(f, _) when float f = 1.5707963267948966 -> FunCall(Var (Ident "acos"), [Float (0.M, "")]) | e -> e diff --git a/tests/commands.txt b/tests/commands.txt index 6a16213c..4e5b890b 100644 --- a/tests/commands.txt +++ b/tests/commands.txt @@ -13,6 +13,7 @@ --no-renaming --format c-array -o tests/unit/operators.expected tests/unit/operators.frag --no-renaming --format c-array -o tests/unit/minus-zero.expected tests/unit/minus-zero.frag --no-renaming --format indented -o tests/unit/inline.expected tests/unit/inline.frag +--no-renaming --format c-array -o tests/unit/float.frag.expected tests/unit/float.frag # Partial renaming tests diff --git a/tests/real/disco.expected b/tests/real/disco.expected index e3249492..11716985 100644 --- a/tests/real/disco.expected +++ b/tests/real/disco.expected @@ -3,4 +3,3 @@ */ var disco_frag = `uniform vec2 resolution;uniform float time;uniform sampler2D tex0,tex1,tex2,tex3;vec4 s(vec2 px,float z){float l=3.1415,k=time*sign(z),x=px.x*320.*.0065*z,y=px.y*240.*.006*z,c=sqrt(x*x+y*y);if(c>1.)return vec4(0.);else{float u=-.4*sign(z)+sin(k*.05),v=sqrt(1.-x*x-y*y),q=y*sin(u)-v*cos(u);y=y*cos(u)+v*sin(u);v=acos(y);u=acos(x/sin(v))/(2.*l)*120.*sign(q)-k;v=v*60./l;q=cos(floor(v/l));c=pow(abs(cos(u)*sin(v)),.2)*.1/(q+sin(float(int((u+l/2.)/l))+k*.6+cos(q*25.)))*pow(1.-c,.9);vec4 res;if(c<0.)res=vec4(-c/2.*abs(cos(k*.1)),0.,-c*2.*abs(sin(k*.04)),1.);else res=vec4(c,c*2.,c*2.,1.);return res;}}void main(){vec2 p=-1.+2.*gl_FragCoord.xy/resolution.xy;vec4 c=vec4(0.);for(int i=80;i>0;i--)c+=s(p,1.-float(i)/80.)*(.008-float(i)*5e-05);vec4 d=s(p,1.);gl_FragColor=(d.w==0.?s(p,-.2)*.02:d)+sqrt(c);}` - diff --git a/tests/real/kinder_painter.expected b/tests/real/kinder_painter.expected index 30352bf1..0c518bc6 100644 --- a/tests/real/kinder_painter.expected +++ b/tests/real/kinder_painter.expected @@ -152,8 +152,8 @@ "vec4 ref;" "vec2 p=-1.+2.*gl_FragCoord.xy/resolution.xy;" "p*=vec2(resolution.x/resolution.y,1.);" - "fpar00[0]=vec4(1.2*sin(2.07342*time),0.,1.8*sin(2.45041*time+1.),1);" - "fpar00[1]=vec4(1.5*sin(1.94776*time+4.),sin(1.8221*time+1.9),1.8*sin(1.8221*time),1);" + "fpar00[0]=vec4(1.2*sin(2.073423*time),0.,1.8*sin(2.450409*time+1.),1);" + "fpar00[1]=vec4(1.5*sin(1.947761*time+4.),sin(1.822099*time+1.9),1.8*sin(1.822099*time),1);" "fpar00[2]=vec4(-1.2,0.,0.,.4);" "fpar00[3]=vec4(1.2,0.,0.,.4);" "fpar00[4]=vec4(0.,1.,0.,2.);" @@ -183,4 +183,3 @@ "col=mix(col,col2,.5-.5*ref.w);" "gl_FragColor=col;" "}", - diff --git a/tests/real/leizex.expected b/tests/real/leizex.expected index 9ae8b84a..21be98b4 100644 --- a/tests/real/leizex.expected +++ b/tests/real/leizex.expected @@ -17,7 +17,7 @@ _leizex_frag: db 'f=f*f*(3.-2.*f);' db 'int n=ip.x+ip.y*57+113*ip.z+sem;' db 'float res=mix(mix(mix(coolfFunc3d2(n+0),coolfFunc3d2(n+1),f.x),mix(coolfFunc3d2(n+57),coolfFunc3d2(n+58),f.x),f.y),mix(mix(coolfFunc3d2(n+113),coolfFunc3d2(n+114),f.x),mix(coolfFunc3d2(n+170),coolfFunc3d2(n+171),f.x),f.y),f.z);' - db 'return 1.-res*9.31323e-10;' + db 'return 1.-res*(1./1073741824.);' db '}' db 'vec2 celular(in vec3 x)' db '{' @@ -29,7 +29,7 @@ _leizex_frag: db 'for(int i=-1;i<=1;i++)' db '{' db 'int nn=ip.x+i+57*(ip.y+j)+113*(ip.z+k);' - db 'vec3 di=vec3(float(i),float(j),float(k))-f+vec3(coolfFunc3d2(nn),coolfFunc3d2(nn+1217),coolfFunc3d2(nn+2513))/2.14748e+09;' + db 'vec3 di=vec3(float(i),float(j),float(k))-f+vec3(coolfFunc3d2(nn),coolfFunc3d2(nn+1217),coolfFunc3d2(nn+2513))/2147483647.;' db 'float d2=dot(di,di);' db 'if(d2