Skip to content

Commit

Permalink
feat: Test are passing for v2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Olian04 committed Jun 18, 2024
1 parent d4b9af2 commit 2e5a6d6
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 154 deletions.
104 changes: 104 additions & 0 deletions src/handles/internal/ctx_utils.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import gleam/float
import gleam/int
import gleam/list
import gleam/result
import handles/ctx
import handles/error

pub fn drill_ctx(
path: List(String),
ctx: ctx.Value,
) -> Result(ctx.Value, error.RuntimeError) {
case path {
[] -> Ok(ctx)
[key, ..rest] ->
case ctx {
ctx.Dict(arr) -> {
case list.find(arr, fn(it) { it.key == key }) {
Ok(ctx.Prop(_, value)) -> drill_ctx(rest, value)
Error(_) -> Error(error.UnknownPropertyError([]))
}
}
ctx.List(_) -> Error(error.UnexpectedTypeError([], "List", ["Dict"]))
ctx.Str(_) -> Error(error.UnexpectedTypeError([], "Str", ["Dict"]))
ctx.Int(_) -> Error(error.UnexpectedTypeError([], "Int", ["Dict"]))
ctx.Float(_) -> Error(error.UnexpectedTypeError([], "Float", ["Dict"]))
ctx.Bool(_) -> Error(error.UnexpectedTypeError([], "Bool", ["Dict"]))
}
}
}

pub fn get_property(
path: List(String),
root_ctx: ctx.Value,
) -> Result(String, error.RuntimeError) {
drill_ctx(path, root_ctx)
|> result.map_error(fn(err) {
case err {
error.UnexpectedTypeError(_, got, expected) ->
error.UnexpectedTypeError(path, got, expected)
error.UnknownPropertyError(_) -> error.UnknownPropertyError(path)
}
})
|> result.try(fn(it) {
case it {
ctx.Str(value) -> value |> Ok
ctx.Int(value) -> value |> int.to_string |> Ok
ctx.Float(value) -> value |> float.to_string |> Ok
ctx.List(_) ->
Error(error.UnexpectedTypeError(path, "List", ["Str", "Int", "Float"]))
ctx.Dict(_) ->
Error(error.UnexpectedTypeError(path, "Dict", ["Str", "Int", "Float"]))
ctx.Bool(_) ->
Error(error.UnexpectedTypeError(path, "Bool", ["Str", "Int", "Float"]))
}
})
}

pub fn get_list(
path: List(String),
root_ctx: ctx.Value,
) -> Result(List(ctx.Value), error.RuntimeError) {
drill_ctx(path, root_ctx)
|> result.map_error(fn(err) {
case err {
error.UnexpectedTypeError(_, got, expected) ->
error.UnexpectedTypeError(path, got, expected)
error.UnknownPropertyError(_) -> error.UnknownPropertyError(path)
}
})
|> result.try(fn(it) {
case it {
ctx.List(value) -> value |> Ok
ctx.Bool(_) -> Error(error.UnexpectedTypeError(path, "Bool", ["List"]))
ctx.Str(_) -> Error(error.UnexpectedTypeError(path, "Str", ["List"]))
ctx.Int(_) -> Error(error.UnexpectedTypeError(path, "Int", ["List"]))
ctx.Float(_) -> Error(error.UnexpectedTypeError(path, "Float", ["List"]))
ctx.Dict(_) -> Error(error.UnexpectedTypeError(path, "Dict", ["List"]))
}
})
}

pub fn get_bool(
path: List(String),
root_ctx: ctx.Value,
) -> Result(Bool, error.RuntimeError) {
drill_ctx(path, root_ctx)
|> result.map_error(fn(err) {
case err {
error.UnexpectedTypeError(_, got, expected) ->
error.UnexpectedTypeError(path, got, expected)
error.UnknownPropertyError(_) -> error.UnknownPropertyError(path)
}
})
|> result.try(fn(it) {
case it {
ctx.Bool(value) -> value |> Ok
ctx.List(_) -> Error(error.UnexpectedTypeError(path, "List", ["Bool"]))
ctx.Str(_) -> Error(error.UnexpectedTypeError(path, "Str", ["Bool"]))
ctx.Int(_) -> Error(error.UnexpectedTypeError(path, "Int", ["Bool"]))
ctx.Float(_) -> Error(error.UnexpectedTypeError(path, "Float", ["Bool"]))
ctx.Dict(_) -> Error(error.UnexpectedTypeError(path, "Dict", ["Bool"]))
}
})
}
180 changes: 29 additions & 151 deletions src/handles/internal/engine.gleam
Original file line number Diff line number Diff line change
@@ -1,110 +1,11 @@
import gleam/float
import gleam/int
import gleam/list
import gleam/bool
import gleam/result
import gleam/string_builder
import handles/ctx
import handles/error
import handles/internal/ctx_utils
import handles/internal/parser

fn drill_ctx(
path: List(String),
ctx: ctx.Value,
) -> Result(ctx.Value, error.RuntimeError) {
case path {
[] -> Ok(ctx)
[key, ..rest] ->
case ctx {
ctx.Dict(arr) -> {
case list.find(arr, fn(it) { it.key == key }) {
Ok(ctx.Prop(_, value)) -> drill_ctx(rest, value)
Error(_) -> Error(error.UnknownPropertyError([]))
}
}
ctx.List(_) -> Error(error.UnexpectedTypeError([], "List", ["Dict"]))
ctx.Str(_) -> Error(error.UnexpectedTypeError([], "Str", ["Dict"]))
ctx.Int(_) -> Error(error.UnexpectedTypeError([], "Int", ["Dict"]))
ctx.Float(_) -> Error(error.UnexpectedTypeError([], "Float", ["Dict"]))
ctx.Bool(_) -> Error(error.UnexpectedTypeError([], "Bool", ["Dict"]))
}
}
}

fn get_property(
path: List(String),
root_ctx: ctx.Value,
) -> Result(String, error.RuntimeError) {
drill_ctx(path, root_ctx)
|> result.map_error(fn(err) {
case err {
error.UnexpectedTypeError(_, got, expected) ->
error.UnexpectedTypeError(path, got, expected)
error.UnknownPropertyError(_) -> error.UnknownPropertyError(path)
}
})
|> result.try(fn(it) {
case it {
ctx.Str(value) -> value |> Ok
ctx.Int(value) -> value |> int.to_string |> Ok
ctx.Float(value) -> value |> float.to_string |> Ok
ctx.List(_) ->
Error(error.UnexpectedTypeError(path, "List", ["Str", "Int", "Float"]))
ctx.Dict(_) ->
Error(error.UnexpectedTypeError(path, "Dict", ["Str", "Int", "Float"]))
ctx.Bool(_) ->
Error(error.UnexpectedTypeError(path, "Bool", ["Str", "Int", "Float"]))
}
})
}

fn get_list(
path: List(String),
root_ctx: ctx.Value,
) -> Result(List(ctx.Value), error.RuntimeError) {
drill_ctx(path, root_ctx)
|> result.map_error(fn(err) {
case err {
error.UnexpectedTypeError(_, got, expected) ->
error.UnexpectedTypeError(path, got, expected)
error.UnknownPropertyError(_) -> error.UnknownPropertyError(path)
}
})
|> result.try(fn(it) {
case it {
ctx.List(value) -> value |> Ok
ctx.Bool(_) -> Error(error.UnexpectedTypeError(path, "Bool", ["List"]))
ctx.Str(_) -> Error(error.UnexpectedTypeError(path, "Str", ["List"]))
ctx.Int(_) -> Error(error.UnexpectedTypeError(path, "Int", ["List"]))
ctx.Float(_) -> Error(error.UnexpectedTypeError(path, "Float", ["List"]))
ctx.Dict(_) -> Error(error.UnexpectedTypeError(path, "Dict", ["List"]))
}
})
}

fn get_bool(
path: List(String),
root_ctx: ctx.Value,
) -> Result(Bool, error.RuntimeError) {
drill_ctx(path, root_ctx)
|> result.map_error(fn(err) {
case err {
error.UnexpectedTypeError(_, got, expected) ->
error.UnexpectedTypeError(path, got, expected)
error.UnknownPropertyError(_) -> error.UnknownPropertyError(path)
}
})
|> result.try(fn(it) {
case it {
ctx.Bool(value) -> value |> Ok
ctx.List(_) -> Error(error.UnexpectedTypeError(path, "List", ["Bool"]))
ctx.Str(_) -> Error(error.UnexpectedTypeError(path, "Str", ["Bool"]))
ctx.Int(_) -> Error(error.UnexpectedTypeError(path, "Int", ["Bool"]))
ctx.Float(_) -> Error(error.UnexpectedTypeError(path, "Float", ["Bool"]))
ctx.Dict(_) -> Error(error.UnexpectedTypeError(path, "Dict", ["Bool"]))
}
})
}

fn run_each(
ctxs: List(ctx.Value),
ast: List(parser.AST),
Expand All @@ -120,6 +21,17 @@ fn run_each(
}
}

fn run_if(
bool: Bool,
children: List(parser.AST),
ctx: ctx.Value,
) -> Result(String, error.RuntimeError) {
case bool {
False -> Ok("")
True -> run(children, ctx, string_builder.new())
}
}

pub fn run(
ast: List(parser.AST),
ctx: ctx.Value,
Expand All @@ -129,60 +41,26 @@ pub fn run(
[] -> builder |> string_builder.to_string |> Ok
[node, ..rest] ->
case node {
parser.Constant(value) ->
run(
rest,
ctx,
builder
|> string_builder.append(value),
)
parser.Property(path) ->
get_property(path, ctx)
|> result.try(fn(it) {
run(
rest,
ctx,
builder
|> string_builder.append(it),
)
})
parser.Constant(value) -> Ok(value)
parser.Property(path) -> ctx_utils.get_property(path, ctx)
parser.IfBlock(path, children) ->
get_bool(path, ctx)
|> result.try(fn(it) {
case it {
False -> run(rest, ctx, builder)
True ->
run(children, ctx, string_builder.new())
|> result.try(fn(it) {
run(
rest,
ctx,
builder
|> string_builder.append(it),
)
})
}
})
ctx_utils.get_bool(path, ctx)
|> result.try(run_if(_, children, ctx))
parser.UnlessBlock(path, children) ->
get_bool(path, ctx)
|> result.try(fn(it) {
case it {
True -> run(rest, ctx, builder)
False ->
run(children, ctx, string_builder.new())
|> result.try(fn(it) {
run(
rest,
ctx,
builder
|> string_builder.append(it),
)
})
}
})
ctx_utils.get_bool(path, ctx)
|> result.map(bool.negate)
|> result.try(run_if(_, children, ctx))
parser.EachBlock(path, children) ->
get_list(path, ctx)
ctx_utils.get_list(path, ctx)
|> result.try(run_each(_, children, string_builder.new()))
}
|> result.try(fn(it) {
run(
rest,
ctx,
builder
|> string_builder.append(it),
)
})
}
}
6 changes: 3 additions & 3 deletions src/handles/internal/parser.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@ pub fn run(tokens: List(tokenizer.Token), ast: List(AST)) -> List(AST) {
tokenizer.Property(path) -> run(tail, [Property(path), ..ast])
tokenizer.IfBlockStart(path) -> {
let children = run(tail, [])
run(list.drop(tail, list.length(children)), [
run(list.drop(tail, list.length(children) + 1), [
IfBlock(path, children),
..ast
])
}
tokenizer.UnlessBlockStart(path) -> {
let children = run(tail, [])
run(list.drop(tail, list.length(children)), [
run(list.drop(tail, list.length(children) + 1), [
UnlessBlock(path, children),
..ast
])
}
tokenizer.EachBlockStart(path) -> {
let children = run(tail, [])
run(list.drop(tail, list.length(children)), [
run(list.drop(tail, list.length(children) + 1), [
EachBlock(path, children),
..ast
])
Expand Down

0 comments on commit 2e5a6d6

Please sign in to comment.