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.