diff options
| author | bringert <bringert@cs.chalmers.se> | 2006-12-05 22:10:28 +0000 |
|---|---|---|
| committer | bringert <bringert@cs.chalmers.se> | 2006-12-05 22:10:28 +0000 |
| commit | 18ec82b54deb9be67a9c541bf69fca0ac020fe9b (patch) | |
| tree | 0cdda01326b69edb3d5b8a7cc078c6f3fcdb767a /src/GF/Canon | |
| parent | 3d68f22b95fcae256f05fb7a35815fd481b876a0 (diff) | |
Got GFCC to JavaScript compilation working. Variants are still printed in a weird way.
Diffstat (limited to 'src/GF/Canon')
| -rw-r--r-- | src/GF/Canon/CanonToJS.hs | 117 |
1 files changed, 98 insertions, 19 deletions
diff --git a/src/GF/Canon/CanonToJS.hs b/src/GF/Canon/CanonToJS.hs index 484ebcac8..d029834fc 100644 --- a/src/GF/Canon/CanonToJS.hs +++ b/src/GF/Canon/CanonToJS.hs @@ -8,41 +8,120 @@ import qualified GF.JavaScript.PrintJS as JS prCanon2js :: CanonGrammar -> String -prCanon2js = JS.printTree . gfcc2js . mkCanon2gfcc +prCanon2js gr = unlines [trees, terms, linearize, utils, (gfcc2js $ mkCanon2gfcc gr)] -gfcc2js :: C.Grammar -> JS.Program -gfcc2js (C.Grm _ _ cs) = concrete2js (head cs) -- FIXME +gfcc2js :: C.Grammar -> String +gfcc2js (C.Grm _ _ cs) = JS.printTree (concrete2js (head cs)) -- FIXME concrete2js :: C.Concrete -> JS.Program -concrete2js (C.Cnc c ds) = JS.Program (map cncdef2js ds) +concrete2js (C.Cnc c ds) = JS.Program ([JS.ElStmt $ JS.SDeclOrExpr $ JS.Decl [JS.DInit (JS.Ident "lin") (new "Array" [])]] + ++ concatMap cncdef2js ds) -cncdef2js :: C.CncDef -> JS.Element +cncdef2js :: C.CncDef -> [JS.Element] cncdef2js (C.Lin (C.CId f) t) = - JS.FunDef (JS.Ident ("lin_"++f)) [children] [JS.Return (term2js t)] + [JS.ElStmt $ JS.SDeclOrExpr $ JS.DExpr $ JS.EAssign (lin (JS.EStr f)) (JS.EFun [children] [JS.SReturn (term2js t)])] term2js :: C.Term -> JS.Expr term2js t = case t of - C.R xs -> call "arr" (map term2js xs) - C.P x y -> JS.EMember (term2js x) (term2js y) - C.S xs -> call "seq" (map term2js xs) + C.R xs -> new "Arr" (map term2js xs) + C.P x y -> JS.ECall (JS.EMember (term2js x) (JS.Ident "sel")) [term2js y] + C.S xs -> new "Seq" (map term2js xs) C.K t -> tokn2js t C.V i -> JS.EIndex (JS.EVar children) (JS.EInt i) - C.C i -> JS.EInt i - C.F (C.CId f) -> call ("lin_"++f) [JS.EVar children] - C.FV xs -> call "variants" (map term2js xs) - C.W str x -> call "suffix" [JS.EStr str, term2js x] - C.RP x y -> call "rp" [term2js x, term2js y] - C.TM -> call "meta" [] - + C.C i -> new "Int" [JS.EInt i] + C.F (C.CId f) -> JS.ECall (lin (JS.EStr f)) [JS.EVar children] + C.FV xs -> new "Variants" (map term2js xs) + C.W str x -> new "Suffix" [JS.EStr str, term2js x] + C.RP x y -> new "Rp" [term2js x, term2js y] + C.TM -> new "Meta" [] + argIdent :: Integer -> JS.Ident argIdent n = JS.Ident ("x" ++ show n) tokn2js :: C.Tokn -> JS.Expr -tokn2js (C.KS s) = JS.EStr s +tokn2js (C.KS s) = new "Str" [JS.EStr s] +tokn2js (C.KP ss vs) = new "Seq" (map JS.EStr ss) -- FIXME children :: JS.Ident children = JS.Ident "cs" -call :: String -> [JS.Expr] -> JS.Expr -call f xs = JS.ECall (JS.EVar (JS.Ident f)) xs +lin :: JS.Expr -> JS.Expr +lin = JS.EIndex (JS.EVar (JS.Ident "lin")) + +new :: String -> [JS.Expr] -> JS.Expr +new f xs = JS.ENew (JS.Ident f) xs + +trees :: String +trees = unlines + [ + "function Fun(name) {", + " this.name = name;", + " this.children = copy_arguments(arguments, 1);", + "}" + ] + +terms :: String +terms = unlines + [ + "function Arr() { this.values = copy_arguments(arguments, 0); }", + "Arr.prototype.print = function() { return this.values[0].print(); }", + "Arr.prototype.sel = function(i) { return this.values[i.toIndex()]; }", + "function Seq() { this.values = copy_arguments(arguments, 0); }", + "Seq.prototype.print = function() { return join_print(this.values, \" \"); }", + "function Variants() { this.values = copy_arguments(arguments, 0); }", + "Variants.prototype.print = function() { return join_print(this.values, \"/\"); }", + "function Glue() { this.values = copy_arguments(arguments, 0); }", + "Glue.prototype.print = function() { return join_print(this.values, \"\"); }", + "function Rp(index,value) { this.index = index; this.value = value; }", + "Rp.prototype.print = function() { return this.index; }", + "Rp.prototype.toIndex = function() { return this.index.toIndex(); }", + "function Suffix(prefix,suffix) { this.prefix = prefix; this.suffix = suffix; }", + "Suffix.prototype.print = function() { return this.prefix.print() + this.suffix.print(); }", + "Suffix.prototype.sel = function(i) { new Glue(this.prefix, this.suffix.sel(i)); }", + "function Meta() { }", + "Meta.prototype.print = function() { return \"?\"; }", + "Meta.prototype.toIndex = function() { return 0; }", + "Meta.prototype.sel = function(i) { return this; }", + "function Str(value) { this.value = value; }", + "Str.prototype.print = function() { return this.value; }", + "function Int(value) { this.value = value; }", + "Int.prototype.print = function() { return this.value; }", + "Int.prototype.toIndex = function() { return this.value; }" + ] + +linearize :: String +linearize = unlines + [ + "function linearize(tree) { return linearizeToTerm(tree).print(); }", + "function linearizeToTerm(tree) {", + " var cs = new Array();", + " for (var i = 0; i < tree.children.length; i++) {", + " cs[i] = linearizeToTerm(tree.children[i]);", + " }", + " return lin[tree.name](cs);", + "}" + ] + +utils :: String +utils = unlines + [ + "function copy_arguments(args, start) {", + " var arr = new Array();", + " for (var i = 0; i < args.length - start; i++) {", + " arr[i] = args[i + start];", + " }", + " return arr;", + "}", + "", + "function join_print(values, glue) {", + " var str = \"\";", + " for (var i = 0; i < values.length; i++) {", + " str += values[i].print();", + " if (i < values.length - 1) {", + " str += glue;", + " }", + " }", + " return str;", + "}" + ] |
