You're welcome. There's still some work to do; I would call it a proof of
concept. But I'll let Marius finish it up. :)


On Thu, Dec 17, 2009 at 10:18 PM, Ross Mellgren <dri...@gmail.com> wrote:

> I like the source for the DSL very much, I think it's very well written.
> Thanks for sharing it.
>
> -Ross
>
> On Dec 17, 2009, at 9:34 PM, Naftoli Gugenheim wrote:
>
> Okay!
> The following code:
>
>>     val jsFunc: JSFunc = Function("myFunc")("param1", "param2") {case
>> param1 :: param2 :: Nil =>
>
>         Var("someArray") := Array(1, 2, 3, 4, 5)
>
>         If(param1 < 30) {
>
>           val x = Var("x")               // now we can use either x or 'x
>
>           x := (234 - 3) / 2             // calculation happens in scala
>
>           Var("y") := (2:Expr) * x * 2   // calculation happens in
>> javascript
>
>           'jsFunc(1, 2, "do it", 'y)
>
>           val $ = JSIdent("$")
>
>           $("#myID") >> 'attr("value", "123")
>
>         } Else {
>
>           'console >> 'log(">=30")
>
>         }
>
>         ForEach(Var("i") In 'someArray) {
>
>           'console >> 'log("Hi there " & 'i)
>
>         }
>
>         Function()("arg1", "arg2") { case arg1 :: arg2 :: Nil =>
>
>           'alert("Anonymous function (" & arg1 & ", " & arg2 & ")")
>
>         }(1,2)
>
>     }
>
>     println(jsFunc.toCode)
>
>
> Produces:
>
> function myFunc(param1, param2) {
>
> var someArray
>
> someArray = [1.0, 2.0, 3.0, 4.0, 5.0]
>
> if((param1 < 30.0)) {
>
> var x
>
> x = 115.0
>
> var y
>
> y = ((2.0 * x) * 2.0)
>
> jsFunc(1.0, 2.0, "do it", y)
>
> ($("#myID")).attr("value", "123")
>
> } else {
>
> (console).log(">=30")
>
> }
>
> var i
>
> for(i in someArray) {
>
> (console).log(("Hi there " + i))
>
> }
>
> function (arg1, arg2) {
>
> alert((((("Anonymous function (" + arg1) + ", ") & arg2) + ")"))
>
> }(1.0, 2.0)
>
> }
>
>
> It may be desirable that instead of defining your own names for Vars and
> function parameters, names are auto-generated, since you can anyway use
> typesafe scala identifiers. This would save boilerplate and produce more
> "obfuscated" code, and other than the name generating algorithm is a trivial
> change to make.
> Note that since I am not familiar with Lift's JavaScript APIs I just wrote
> my own AST, which consists of case classes that contain their data
> parameters and a toCode method. Feel free to delete them and plug Lift's
> classes instead--there is no dependency on anything unique about them.
> Also note that to prevent "string" + ident from compiling as a string to be
> outputted and instead output a + operation, you have two choices: use the &
> operator instead, which is replaced with + when either operand is a string,
> or write ("string":Expr) + ident.
>
>
> 2009/12/17 Naftoli Gugenheim <naftoli...@gmail.com>
>
>> Current state attached.
>>
>>
>> 2009/12/17 Marius <marius.dan...@gmail.com>
>>
>> Let me know when you have something.
>>>
>>> Br's,
>>> Marius
>>>
>>> On Dec 17, 8:58 am, Naftoli Gugenheim <naftoli...@gmail.com> wrote:
>>> > I'm thinking of an approach to writing a DSL with a much cleaner
>>> syntax. I'll try to put something together.
>>> >
>>> > -------------------------------------
>>> >
>>> > Marius Danciu<marius.dan...@gmail.com> wrote:
>>> >
>>> > All,
>>> >
>>> > I just want to see if there is any interest in the approach discussed
>>> here.
>>> > As you know Lift has some interesting support for building JavaScript
>>> > constructs from Scala code usig JsExp, JsCmd etc classes. I used quite
>>> a lot
>>> > this support and it's great but if your JS code that you want to send
>>> down
>>> > to the browser (say as an Ajax or Comet partial update response) gets a
>>> bit
>>> > more complicated then constructing the JS fragment leads IMO to some
>>> > cumbersome Scala code. I found myselft in quite a few situation to use
>>> JsRaw
>>> > to write the JavaScript fragment in order for the code reader to
>>> understand
>>> > what JavaScript code will be generated. But of course with JsRaw we put
>>> > everything into a String so I'm not a big fan of this approach. So I
>>> started
>>> > to define a JavaScript like "DSL" that IMO is closer to JavaScript
>>> form.
>>> > Attached is a source code smaple of how this looks like, so for
>>> instance we
>>> > can have something like:
>>> >
>>> > val js = JsFunc('myFunc, 'param1, 'param2) {
>>> >     JsIf('param1 __< 30) {
>>> >         Var('home) := Wrap(234 __- 3) __/ 2 `;`
>>> >         Var('someArray) := JsArray(1, 2, 3, 4, 5) `;`
>>> >         'myFunc(1, 2, "do it", 'home) `;`
>>> >         $("#myID") >> 'attr("value", "123") `;`
>>> >       } ~
>>> >       JsForEach(Var('i) in 'someArray) {
>>> >         'console >> 'log("Hi there " __+ 'i) `;`
>>> >       } ~
>>> >       JsAnonFunc('arg1, 'arg2) {
>>> >        'alert("Anonymous function " __+ 'arg1 __+ 'arg2)
>>> >       }(1, 2) `;`
>>> >     }
>>> >
>>> >     println(js.toJs)
>>> >
>>> > this yields the following JavaScript code:
>>> >
>>> > function myFunc( param1, param2 ) {
>>> > if (param1 < 30) {
>>> > var home = ( 234 - 3 ) / 2;
>>> > var someArray = [ 1, 2, 3, 4, 5 ];
>>> > myFunc(1, 2, "do it", home);
>>> > $("#myID").attr("value", "123");}
>>> >
>>> > for (var i in someArray) {
>>> > console.log("Hi there " + i);}
>>> >
>>> > function ( arg1, arg2 ) {
>>> > alert("Anonymous function " + arg1 + arg2)
>>> >
>>> > }(1, 2);
>>> > }
>>> >
>>> > ... ok I just droped nonsense code in there for exemplification. A few
>>> > words:
>>> >
>>> > 1. JsIf, JsForEach describe JavaScript if and for(each) statements
>>> > 2. Functions like __<, __>, ... __+, __- are function that alows
>>> definition
>>> > of boolean and/or algebraic expressions.
>>> > 3. Wrap just wraps an expression into ()
>>> > 4. Var defined a variable
>>> > 5 := defines an assignment
>>> > 6. JsFunc declares a JS function
>>> > 7. JsAnonFunc declares an anonymous function
>>> > 8. 'myFunc(1, 2, "do it", 'home)  is simply a javascript function
>>> invocation
>>> > by providing 4 parameter.
>>> > 9. ~ is just a function that chains statements that don;t necessarily
>>> end in
>>> > ;
>>> >
>>> > Do you think that something like this would be usable in Lift?
>>> >
>>> > Br's,
>>> > Marius
>>> >
>>> > --
>>> >
>>> > You received this message because you are subscribed to the Google
>>> Groups "Lift" group.
>>> > To post to this group, send email to lift...@googlegroups.com.
>>> > To unsubscribe from this group, send email to
>>> liftweb+unsubscr...@googlegroups.com<liftweb%2bunsubscr...@googlegroups.com>
>>> .
>>> > For more options, visit this group athttp://
>>> groups.google.com/group/liftweb?hl=en.
>>>
>>> --
>>>
>>> You received this message because you are subscribed to the Google Groups
>>> "Lift" group.
>>> To post to this group, send email to lift...@googlegroups.com.
>>> To unsubscribe from this group, send email to
>>> liftweb+unsubscr...@googlegroups.com<liftweb%2bunsubscr...@googlegroups.com>
>>> .
>>> For more options, visit this group at
>>> http://groups.google.com/group/liftweb?hl=en.
>>>
>>>
>>>
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Lift" group.
> To post to this group, send email to lift...@googlegroups.com.
> To unsubscribe from this group, send email to
> liftweb+unsubscr...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/liftweb?hl=en.
> <DSL.scala>
>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "Lift" group.
> To post to this group, send email to lift...@googlegroups.com.
> To unsubscribe from this group, send email to
> liftweb+unsubscr...@googlegroups.com<liftweb%2bunsubscr...@googlegroups.com>
> .
> For more options, visit this group at
> http://groups.google.com/group/liftweb?hl=en.
>

--

You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.


Reply via email to