git-subtree-dir: dotscape git-subtree-mainline:6b91d64fc3git-subtree-split:f306501a68
83 lines
2.7 KiB
Standard ML
83 lines
2.7 KiB
Standard ML
structure Parser =
|
|
struct
|
|
structure T = Tokens
|
|
|
|
fun parseItem (tokens, grid) =
|
|
case tokens of
|
|
T.L_BRACE ::
|
|
T.INT x ::
|
|
T.INT y ::
|
|
T.INT ex ::
|
|
T.INT ey ::
|
|
T.INT r :: T.INT g :: T.INT b :: T.INT a :: T.R_BRACE :: tl =>
|
|
let
|
|
val colour = {r = r, g = g, b = b, a = a}
|
|
val grid = ParseGrid.applyItem (grid, x, y, ex, ey, colour)
|
|
in
|
|
SOME (tl, grid)
|
|
end
|
|
| _ => NONE
|
|
|
|
(* note to be careful of:
|
|
* - startParseItems returns NONE if there are no items found,
|
|
* because we have not found a single item yet.
|
|
*
|
|
* - loopParseItems returns SOME if there are no items found,
|
|
* because this function is called after we have parsed at least one item.
|
|
* *)
|
|
fun loopParseItems (tokens, grid) =
|
|
case parseItem (tokens, grid) of
|
|
SOME (tokens, grid) => loopParseItems (tokens, grid)
|
|
| NONE => SOME (tokens, grid)
|
|
|
|
fun startParseItems (tokens, grid) =
|
|
case parseItem (tokens, grid) of
|
|
SOME (tokens, grid) => loopParseItems (tokens, grid)
|
|
| NONE => NONE
|
|
|
|
fun parseLayer (tokens, canvasWidth, canvasHeight, tree, counter) =
|
|
case tokens of
|
|
T.L_BRACKET :: tl =>
|
|
let
|
|
val grid = ParseGrid.make (canvasWidth, canvasHeight)
|
|
in
|
|
case startParseItems (tl, grid) of
|
|
SOME (T.R_BRACKET :: tl, grid) =>
|
|
let val tree = LayerTree.insert (counter, grid, tree)
|
|
in SOME (tl, tree)
|
|
end
|
|
| SOME _ => NONE
|
|
| NONE => NONE
|
|
end
|
|
| _ => NONE
|
|
|
|
fun parseLayerLoop (tokens, canvasWidth, canvasHeight, tree, counter) =
|
|
case parseLayer (tokens, canvasWidth, canvasHeight, tree, counter) of
|
|
SOME (tl, tree) =>
|
|
parseLayerLoop (tl, canvasWidth, canvasHeight, tree, counter + 1)
|
|
| NONE => SOME (tokens, tree)
|
|
|
|
fun startParseLayer (tokens, canvasWidth, canvasHeight, tree) =
|
|
case parseLayer (tokens, canvasWidth, canvasHeight, tree, 1) of
|
|
SOME (tl, tree) => parseLayerLoop (tl, canvasWidth, canvasHeight, tree, 2)
|
|
| NONE => NONE
|
|
|
|
fun parse string =
|
|
case Lexer.scan string of
|
|
SOME tokens =>
|
|
(case tokens of
|
|
T.INT canvasWidth :: T.INT canvasHeight :: T.L_BRACE :: tl =>
|
|
let
|
|
val maxSide = Int.max (canvasWidth, canvasHeight)
|
|
val tree = LayerTree.init maxSide
|
|
in
|
|
case startParseLayer (tl, canvasWidth, canvasHeight, tree) of
|
|
SOME ([T.R_BRACE], tree) =>
|
|
SOME (canvasWidth, canvasHeight, tree)
|
|
| SOME _ => NONE
|
|
| NONE => NONE
|
|
end
|
|
| _ => NONE)
|
|
| NONE => NONE
|
|
end
|