Skip to content

Commit

Permalink
merge fixes from other repo
Browse files Browse the repository at this point in the history
  • Loading branch information
CrowdHailer committed Aug 24, 2024
2 parents 411c526 + 5c23f41 commit 260ef51
Show file tree
Hide file tree
Showing 77 changed files with 1,652 additions and 387 deletions.
2 changes: 2 additions & 0 deletions eyg/src/atelier/app.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ fn insert(zipper: zipper.Zipper, state) {
e.Handle(label) -> Ok(write(label, e.Handle))
e.Shallow(label) -> Ok(write(label, e.Shallow))
e.Builtin(_) -> Error("no insert option for builtin, use stdlib references")
e.Reference(_) ->
Error("no insert option for reference, use stdlib references")
})

Ok(WorkSpace(..state, mode: mode))
Expand Down
1 change: 1 addition & 0 deletions eyg/src/atelier/view/projection.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pub fn do_render(exp, br, loc, inferred) {
e.Handle(label) -> [handle(label, loc, inferred)]
e.Shallow(label) -> [shallow(label, loc, inferred)]
e.Builtin(id) -> [builtin(id, loc, inferred)]
e.Reference(id) -> [builtin(id, loc, inferred)]
}
}

Expand Down
11 changes: 11 additions & 0 deletions eyg/src/browser_ffi.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// https://stackoverflow.com/questions/6122571/simple-non-secure-hash-function-for-javascript
export function hashCode(str) {
let hash = 0;
for (let i = 0, len = str.length; i < len; i++) {
let chr = str.charCodeAt(i);
hash = (hash << 5) - hash + chr;
// hash |= 0; // Convert to 32bit integer
hash = hash >>> 0
}
return hash.toString(16);
}
11 changes: 0 additions & 11 deletions eyg/src/drafting/README.md

This file was deleted.

5 changes: 4 additions & 1 deletion eyg/src/drafting/state.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,10 @@ fn insert_perform(source, context) {
}

fn increase(source) {
#(navigation.increase(source), Command(None))
case navigation.increase(source) {
Ok(source) -> #(source, Command(None))
Error(Nil) -> #(source, Command(Some(ActionFailed("increase selection"))))
}
}

fn insert_string(source) {
Expand Down
3 changes: 2 additions & 1 deletion eyg/src/easel/embed.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ pub fn handle_click(root, event) {
// r.resumable(source, stdlib.env(), None)
// let assert Ok(tenv) = dict.get(envs, rev)
io.debug("inferring")
j.infer(source, tj.Empty, 0, j.new_state())
j.infer(source, tj.Empty, dict.new(), 0, j.new_state())
io.debug("inferred")

let env = stdlib.env()
Expand Down Expand Up @@ -1323,6 +1323,7 @@ fn to_html(sections) {
print.Label -> ["text-blue-3"]
print.Effect -> ["text-yellow-4"]
print.Builtin -> ["italic underline"]
print.Reference -> ["italic underline"]
}
let class =
case err {
Expand Down
3 changes: 3 additions & 0 deletions eyg/src/easel/print.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub type Style {
Label
Effect
Builtin
Reference
}

pub type Rendered =
Expand Down Expand Up @@ -272,6 +273,8 @@ fn do_print(source, loc: Location, br, acc, info, analysis) {
}
e.Builtin(value) ->
print_with_offset(value, loc, Builtin, err, acc, info, analysis)
e.Reference(value) ->
print_with_offset(value, loc, Reference, err, acc, info, analysis)
}
}

Expand Down
41 changes: 6 additions & 35 deletions eyg/src/examine/state.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import eyg/parse
import eyg/runtime/cast
import eyg/runtime/interpreter/live
import eyg/runtime/value as v
import eyg/text/text
import eygir/annotated
import gleam/bit_array
import gleam/dict
import gleam/io
import gleam/javascript as js
import gleam/list
import gleam/option.{type Option, None, Some}
import gleam/result
import gleam/string
import harness/effect as impl
import lustre/effect
import plinth/browser/document
Expand All @@ -34,35 +33,6 @@ pub fn source(state: State) {
state.source
}

pub fn lines(source) {
list.reverse(do_lines(source, 0, 0, []))
}

fn do_lines(source, offset, start, acc) {
case source {
"\r\n" <> rest -> {
let offset = offset + 2
do_lines(rest, offset, offset, [start, ..acc])
}
"\n" <> rest -> {
let offset = offset + 1
do_lines(rest, offset, offset, [start, ..acc])
}
_ ->
case string.pop_grapheme(source) {
Ok(#(g, rest)) -> {
let offset = offset + byte_size(g)
do_lines(rest, offset, start, acc)
}
Error(Nil) -> [start, ..acc]
}
}
}

fn byte_size(string: String) -> Int {
bit_array.byte_size(<<string:utf8>>)
}

pub fn apply_span(lines, span, thing, acc) {
let #(from, to) = span
case lines {
Expand Down Expand Up @@ -99,7 +69,7 @@ pub fn highlights(state, spans, acc) {
let with_effects =
list.fold(
effect_lines(spans, acc),
list.map(lines(source(state)), fn(x) { #(x, []) }),
list.map(text.line_offsets(source(state)), fn(x) { #(x, []) }),
fn(lines, sp) { apply_span(lines, sp.0, sp.1, []) },
)

Expand Down Expand Up @@ -133,7 +103,8 @@ pub fn information(state) {
case parse.from_string(source(state)) {
Ok(#(tree, _rest)) -> {
let #(tree, spans) = annotated.strip_annotation(tree)
let #(exp, bindings) = j.infer(tree, t.Empty, 0, j.new_state())
let #(exp, bindings) =
j.infer(tree, t.Empty, dict.new(), 0, j.new_state())
let acc = annotated.strip_annotation(exp).1
let acc =
list.map(acc, fn(node) {
Expand Down Expand Up @@ -165,7 +136,7 @@ pub fn interpret(state) {
case parse.from_string(source(state)) {
Ok(#(tree, _rest)) -> {
let #(r, assignments) = live.execute(tree, h)
let lines = list.map(lines(source(state)), fn(x) { #(x, []) })
let lines = list.map(text.line_offsets(source(state)), fn(x) { #(x, []) })
let output =
list.fold(assignments, lines, fn(lines, sp) {
apply_span(lines, sp.2, Ok(#(sp.0, sp.1)), [])
Expand All @@ -184,7 +155,7 @@ pub fn interpret(state) {
pub fn compile(state) {
case parse.from_string(source(state)) {
Ok(#(tree, _rest)) -> {
Ok(compile.to_js(tree))
Ok(compile.to_js(tree, dict.new()))
}
Error(reason) -> Error(reason)
}
Expand Down
4 changes: 3 additions & 1 deletion eyg/src/eyg.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import eyg/analysis/type_/isomorphic as t
import eygir/annotated
import eygir/annotated as e
import eygir/decode
import gleam/dict
import gleam/io
import gleam/javascript/array
import gleam/javascript/promise
Expand Down Expand Up @@ -36,7 +37,8 @@ pub fn do_main(args) {
case args {
["exec", ..] -> shell.run(e.add_annotation(source, Nil))
["infer"] -> {
let #(exp, bindings) = infer.infer(source, t.Empty, 0, infer.new_state())
let #(exp, bindings) =
infer.infer(source, t.Empty, dict.new(), 0, infer.new_state())
let acc = annotated.strip_annotation(exp).1
let errors =
list.filter_map(acc, fn(row) {
Expand Down
1 change: 1 addition & 0 deletions eyg/src/eyg/analysis/inference.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ fn do_infer(env, exp, typ, eff, ref, path) {
dict.new(),
)
}
e.Reference(_) -> panic as "not supported in this inference"
}
|> compose(Infered(
sub.none(),
Expand Down
46 changes: 27 additions & 19 deletions eyg/src/eyg/analysis/inference/levels_j/contextual.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ pub fn new_state() {
dict.new()
}

pub fn infer(source, eff, level, bindings) {
let #(bindings, _type, _eff, acc) = do_infer(source, [], eff, level, bindings)
pub fn infer(source, eff, refs, level, bindings) {
let #(bindings, _type, _eff, acc) =
do_infer(source, [], eff, refs, level, bindings)
#(acc, bindings)
}

Expand Down Expand Up @@ -91,7 +92,10 @@ fn eff_tail(eff) {
}
}

pub fn do_infer(source, env, eff, level, bindings) {
pub type Env =
List(#(String, binding.Poly))

pub fn do_infer(source, env, eff, refs: dict.Dict(_, _), level, bindings) {
case source {
e.Variable(x) ->
case list.key_find(env, x) {
Expand All @@ -115,7 +119,7 @@ pub fn do_infer(source, env, eff, level, bindings) {
let #(type_eff, bindings) = binding.mono(level, bindings)

let #(bindings, type_r, type_eff, inner) =
do_infer(body, [#(x, scheme_x), ..env], type_eff, level, bindings)
do_infer(body, [#(x, scheme_x), ..env], type_eff, refs, level, bindings)

let type_ = t.Fun(type_x, type_eff, type_r)
let level = level - 1
Expand All @@ -128,9 +132,9 @@ pub fn do_infer(source, env, eff, level, bindings) {
// not the effect of applying them
let level = level + 1
let #(bindings, ty_fun, eff, fun) =
do_infer(fun, env, eff, level, bindings)
do_infer(fun, env, eff, refs, level, bindings)
let #(bindings, ty_arg, eff, arg) =
do_infer(arg, env, eff, level, bindings)
do_infer(arg, env, eff, refs, level, bindings)

let #(ty_ret, bindings) = binding.mono(level, bindings)
let #(test_eff, bindings) = binding.mono(level, bindings)
Expand Down Expand Up @@ -180,13 +184,13 @@ pub fn do_infer(source, env, eff, level, bindings) {
e.Let(label, value, then) -> {
let level = level + 1
let #(bindings, ty_value, eff, value) =
do_infer(value, env, eff, level, bindings)
do_infer(value, env, eff, refs, level, bindings)
let level = level - 1
let sch_value =
binding.gen(close(ty_value, level, bindings), level, bindings)

let #(bindings, ty_then, eff, then) =
do_infer(then, [#(label, sch_value), ..env], eff, level, bindings)
do_infer(then, [#(label, sch_value), ..env], eff, refs, level, bindings)
let meta = #(Ok(Nil), ty_then, t.Empty, env)
#(bindings, ty_then, eff, #(a.Let(label, value, then), meta))
}
Expand Down Expand Up @@ -217,18 +221,22 @@ pub fn do_infer(source, env, eff, level, bindings) {
// TODO actual inference
e.Shallow(label) ->
prim(handle(label), env, eff, level, bindings, a.Shallow(label))
e.Builtin(identifier) ->
case builtin(identifier) {
Ok(poly) -> prim(poly, env, eff, level, bindings, a.Builtin(identifier))
e.Builtin(id) ->
case builtin(id) {
Ok(poly) -> prim(poly, env, eff, level, bindings, a.Builtin(id))
Error(Nil) -> {
let #(type_, bindings) = binding.mono(level, bindings)
let meta = #(Error(error.MissingVariable(id)), type_, t.Empty, env)
#(bindings, type_, eff, #(a.Builtin(id), meta))
}
}
e.Reference(id) ->
case dict.get(refs, id) {
Ok(poly) -> prim(poly, env, eff, level, bindings, a.Reference(id))
Error(Nil) -> {
let #(type_, bindings) = binding.mono(level, bindings)
let meta = #(
Error(error.MissingVariable(identifier)),
type_,
t.Empty,
env,
)
#(bindings, type_, eff, #(a.Builtin(identifier), meta))
let meta = #(Error(error.MissingReference(id)), type_, t.Empty, env)
#(bindings, type_, eff, #(a.Reference(id), meta))
}
}
}
Expand All @@ -254,7 +262,7 @@ fn pure3(arg1, arg2, arg3, ret) {
}

// q for quantified
fn q(i) {
pub fn q(i) {
t.Var(#(True, i))
}

Expand Down
4 changes: 3 additions & 1 deletion eyg/src/eyg/analysis/jm/tree.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ fn primitive(exp, next) {
| e.Apply(_, _)
| e.Lambda(_, _)
| e.Let(_, _, _)
| e.Builtin(_) -> panic("not a literal")
| e.Builtin(_) -> panic as "not a literal"

e.Reference(_) -> panic as "not implemented in this type checker"

e.Binary(_) -> #(t.Binary, next)
e.Str(_) -> #(t.String, next)
Expand Down
1 change: 1 addition & 0 deletions eyg/src/eyg/analysis/type_/binding/debug.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub fn render_reason(reason) {
case reason {
error.MissingVariable(label) ->
string.concat(["missing variable '", label, "'"])
error.MissingReference(label) -> "missing reference #" <> label
error.MissingRow(label) -> string.concat(["missing row '", label, "'"])
error.TypeMismatch(expected, given) ->
string.concat([
Expand Down
14 changes: 14 additions & 0 deletions eyg/src/eyg/analysis/type_/binding/error.gleam
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import eyg/analysis/type_/binding
import gleam/list

pub type Reason {
MissingVariable(String)
MissingReference(String)
TypeMismatch(binding.Mono, binding.Mono)
MissingRow(String)
Recursive
}

// only looks through errors internal replacements are already in the cache
pub fn missing_references(errors) {
list.filter_map(errors, fn(error) {
let #(_path, reason) = error
case reason {
MissingReference(ref) -> Ok(ref)
_ -> Error(Nil)
}
})
|> list.unique()
}
9 changes: 8 additions & 1 deletion eyg/src/eyg/analysis/type_/binding/unify.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ import gleam/io
import gleam/result.{try}

pub fn unify(t1, t2, level, bindings) {
do_unify([#(t1, t2)], level, bindings)
case do_unify([#(t1, t2)], level, bindings) {
Error(error.TypeMismatch(t.Var(x), t.Var(y))) ->
Error(error.TypeMismatch(
binding.resolve(t1, bindings),
binding.resolve(t2, bindings),
))
result -> result
}
}

// https://github.com/7sharp9/write-you-an-inference-in-fsharp/blob/master/HMPure-Rowpolymorphism/HMPureRowpolymorphism.fs
Expand Down
4 changes: 4 additions & 0 deletions eyg/src/eyg/analysis/type_/isomorphic.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ pub fn result(value, reason) {
Union(RowExtend("Ok", value, RowExtend("Error", reason, Empty)))
}

pub fn option(value) {
Union(RowExtend("Some", value, RowExtend("None", unit, Empty)))
}

pub const file = Record(
RowExtend("name", String, RowExtend("content", Binary, Empty)),
)
Expand Down
Loading

0 comments on commit 260ef51

Please sign in to comment.