Haskell-Things / ImplicitCAD

A math-inspired CAD program in haskell. CSG, bevels, and shells; 2D & 3D geometry; 2D gcode generation...
https://implicitcad.org/
GNU Affero General Public License v3.0
1.41k stars 142 forks source link

openscad quasiquote #480

Open aavogt opened 9 months ago

aavogt commented 9 months ago

I like circle($fn=6), but I don't see it in the haskell api. While it is possible to encode such optional arguments in haskell, I think a quasiquoter would be better.

hex1 d = [scad| circle(d, $fn=6) |] -- too light
hex2 d = [scad2d| circle($$d, $fn=6) |] -- too heavy
hex3 d = [scad| circle($(d), $fn=6) |] -- just right?
ovitus commented 2 months ago

Second this. How can this be done via Haskell?

aavogt commented 2 months ago

https://github.com/Haskell-Things/ImplicitCAD/blob/master/programs/extopenscad.hs#L168 shows how it parses scad/runs scad files. SymbolicObj3 contains functions, so the QuasiQuoter probably has to run the parser at runtime because there's no Lift instance, ie. it probably will look like:

-- | QuasiQuoter for extopenscad expressions
-- 
-- > hex ::  Double -> IO SymbolicObj2
-- > hex d = [scad2d| circle($(d), $fn=6) |]
scad2d = QuasiQuoter { quoteExp = \ str -> do
  checkSyntax str -- optional: probably calls runOpenscad
  [| (\(_,obj2s,_obj3s,_) -> obj2s) <$> runOpenscad scadOpts _ $(antiquote str) |] }

-- | > antiquote "ab $(c) def" == [| "ab " ++ show c ++ " def" |]
antiquote :: String -> ExpQ
antiquote = _

But maybe the result doesn't have to be in IO.