Skip to content

Commit

Permalink
Add support for field access when looking up functions and variants
Browse files Browse the repository at this point in the history
  • Loading branch information
dusty-phillips committed Sep 17, 2024
1 parent 73c24d3 commit e637e13
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/glimpse/error.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub type TypeCheckError {
InvalidArguments(expected: String, actual_arguments: String)
InvalidArgumentLabel(expected: String, got: String)
DuplicateCustomType(name: String)
InvalidFieldAccess(container: String, label: String)
}

pub type TypeCheckResult(a) =
Expand Down
16 changes: 16 additions & 0 deletions src/glimpse/internal/typecheck.gleam
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import glance
import gleam/dict
import gleam/list
import gleam/option
import gleam/result
Expand Down Expand Up @@ -111,6 +112,21 @@ pub fn expression(
}
}

glance.FieldAccess(container, label) -> {
use container_expression_type <- result.try(expression(
environment,
container,
))
case container_expression_type {
types.NamespaceType(nested_env) ->
nested_env
|> dict.get(label)
|> result.replace_error(error.InvalidName(label))
type_ ->
Error(error.InvalidFieldAccess(type_ |> types.to_string, label))
}
}

glance.Call(target, arguments) -> call(environment, target, arguments)

glance.BinaryOperator(operator, left, right) ->
Expand Down
2 changes: 1 addition & 1 deletion src/glimpse/internal/typecheck/environment.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ pub fn type_(environment: Environment, glance_type: glance.Type) -> TypeResult {
glance.VariableType(name) -> lookup_variable_type(environment, name)
_ -> {
pprint.debug(glance_type)
todo
todo as "many glance types not processed yet"
}
}
}
61 changes: 61 additions & 0 deletions test/typecheck/imports_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,64 @@ pub fn import_no_add_private_variant_to_env_test() {
|> should.be_ok
|> should.equal(types.NamespaceType(dict.from_list([])))
}

pub fn import_call_function_field_access_test() {
let #(_, foo_env) = helpers.ok_module_typecheck("pub fn bar() -> Nil {}")

let other_envs = dict.from_list([#("foo", foo_env)])

let #(_, main_env) =
glance.module(
"import foo
pub fn main() -> Nil {
foo.bar()
}",
)
|> should.be_ok
|> glimpse.Module("main_module", _, ["foo"])
|> typecheck.module(other_envs)
|> should.be_ok

main_env.definitions
|> assertions.should_have_dict_size(2)
|> dict.get("foo")
|> should.be_ok
|> should.equal(
types.NamespaceType(
dict.from_list([
#("bar", types.CallableType([], dict.new(), types.NilType)),
]),
),
)
}

pub fn variant_call_function_field_access_test() {
let #(_, foo_env) = helpers.ok_module_typecheck("pub type Foo {Foo}")

let other_envs = dict.from_list([#("foo", foo_env)])

let #(_, main_env) =
glance.module(
"import foo
pub fn main() -> Nil {
foo.Foo()
Nil
}",
)
|> should.be_ok
|> glimpse.Module("main_module", _, ["foo"])
|> typecheck.module(other_envs)
|> should.be_ok

main_env.definitions
|> assertions.should_have_dict_size(2)
|> dict.get("foo")
|> should.be_ok
|> should.equal(
types.NamespaceType(
dict.from_list([
#("Foo", types.CallableType([], dict.new(), types.CustomType("Foo"))),
]),
),
)
}
17 changes: 17 additions & 0 deletions test/typecheck/package_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,20 @@ pub fn typecheck_dependent_module_package_test() {
}
})
}

pub fn typecheck_call_to_dependent_module_package_test() {
helpers.ok_package_check("main_module", fn(pkg) {
case pkg {
"main_module" ->
Ok(
"import other/package
pub fn main() -> Nil {
package.other()
}",
)
"other/package" -> Ok("pub fn other() -> Nil {}")
_ -> panic as "only two modules in this test"
}
})
}

0 comments on commit e637e13

Please sign in to comment.