~cypheon/rapid

ref: 9928b2ee6ed80e49271a11f7254409cdad7a574f rapid/src/Control/Codegen.idr -rw-r--r-- 1.9 KiB
9928b2ee — Johann Rudloff [refactor] Codegen: use simpler state modification methods 4 months ago
                                                                                
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
module Control.Codegen

import public Control.Monad.State
import Data.List
import Data.String

import Debug.Trace
import Rapid.Common

ConstDef : Type
ConstDef = (String, String)

export
record CGBuffer where
  constructor MkCGBuf
  opts : CompileOpts
  i : Int
  consts : List ConstDef
  code : List String
  errors : List String

public export
Codegen : Type -> Type
Codegen = State CGBuffer

emptyCG : CompileOpts -> CGBuffer
emptyCG opts = MkCGBuf opts 0 [] [] []

export
getOpts : Codegen CompileOpts
getOpts = (.opts) <$> get

export
appendCode : String -> Codegen ()
appendCode c = modify { code $= (c::)}

export
getUnique : Codegen Int
getUnique = do
  st <- get
  let i = st.i
  put ({i := i+1} st)
  pure i

export
addConstant : String -> Codegen String
addConstant v = do
  ci <- getUnique
  st <- get
  let name = "@glob_" ++ show (st.opts.constNamespace) ++ "_c" ++ show ci
  put ({ consts $= ((name, v)::)} st)
  pure name

export
addError : String -> Codegen ()
addError msg = do
  appendCode ("; ERROR: " ++ msg)
  st <- get
  put $ trace ("add error: " ++ msg) ({errors $= (msg::)} st)

export
addMetadata : String -> Codegen String
addMetadata v = do
  i <- (.constNamespace) <$> getOpts
  u <- getUnique
  let mdId = u * 0x10000 + i
  let name = "!" ++ show mdId
  modify { consts $= ((name, v)::)}
  pure name

export
appendMetadata : String -> Codegen String
appendMetadata value = do
  o <- (.constNamespace) <$> getOpts
  i <- getUnique
  let varname = "!" ++ show (i * 1000000 + o)
  appendCode ("  " ++ varname ++ " = " ++ value)
  pure varname

export
mkVarName : String -> Codegen String
mkVarName pfx = do
  i <- getUnique
  pure $ (pfx ++ show i)

export
runCodegen : CompileOpts -> Codegen () -> String
runCodegen o r = let (MkCGBuf _ _ cs ls errors) = fst $ runState (emptyCG o) r in
                     fastConcat $ intersperse "\n" $ (map (\(n,v) => n ++ " = " ++ v) $ reverse cs) ++ reverse ls