summaryrefslogtreecommitdiff
path: root/examples/gfcc/ImperC.gf
blob: ec78504f357c81bf0d3b13fe12fc22b906ca5dab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
--# -path=.:../prelude

concrete ImperC of Imper = open Prelude, Precedence, ResImper in {

flags lexer=codevars ; unlexer=code ; startcat=Stm ;

-- code inside function bodies

  lincat
    Stm = SS ;
    Typ = SS ;
    Exp = PrecExp ;
    Var = SS ;

  lin
    Decl  typ cont = continue  (typ.s ++ cont.$0) cont ;
    Assign _ x exp = continue  (x.s ++ "=" ++ ex exp) ;
    Return _ exp   = statement ("return" ++ ex exp) ;
    While exp loop = continue  ("while" ++ paren (ex exp) ++ loop.s) ;
    Block stm      = continue  ("{" ++ stm.s ++ "}") ;
    End            = statement [] ;
 
    EVar  _ x  = constant x.s ;
    EInt    n  = constant n.s ;
    EFloat a b = constant (a.s ++ "." ++ b.s) ;
    EMulI      = infixL p3 "*" ;
    EMulF      = infixL p3 "*" ;
    EAddI      = infixL p2 "+" ;
    EAddF      = infixL p2 "+" ;
    ELtI       = infixN p1 "<" ;
    ELtF       = infixN p1 "<" ;

    TInt       = ss "int" ;
    TFloat     = ss "float" ;

-- top-level code consisting of function definitions
 
  lincat
    Program = SS ;
    Typs = SS ;
    Fun = SS ;
    Body = {s,s2 : Str ; size : Size} ;
    Exps = {s    : Str ; size : Size} ;

  lin
    Empty = ss [] ;
    Funct args val body cont = ss (
      val.s ++ cont.$0 ++ paren body.s2 ++ "{" ++ 
        body.s ++ 
      "}" ++ ";" ++ 
      cont.s
      ) ;

    NilTyp = ss [] ;
    ConsTyp = cc2 ;

    BodyNil stm = stm ** {s2 = [] ; size = Zero} ;
    BodyCons typ _ body = {
      s  = body.s ; 
      s2 = typ.s ++ body.$0 ++ separator "," body.size ++ body.s2 ;
      size = nextSize body.size
      } ;

    EApp args val f exps = constant (f.s ++ paren exps.s) ;

    NilExp = ss [] ** {size = Zero} ;
    ConsExp _ _ e es = {
      s = ex e ++ separator "," es.size ++ es.s ;
      size = nextSize es.size
      } ;
}