Skip to content

Commit

Permalink
Add some mathy binops
Browse files Browse the repository at this point in the history
  • Loading branch information
dusty-phillips committed Sep 11, 2024
1 parent e4b5923 commit d653bbd
Show file tree
Hide file tree
Showing 6 changed files with 424 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/glimpse/error.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@ pub type GlimpseImportError {
pub type TypeCheckError {
InvalidReturnType(function_name: String, got: String, expected: String)
InvalidName(name: String)
InvalidBinOp(
operator: String,
left_got: String,
right_got: String,
expected: String,
)
}
83 changes: 83 additions & 0 deletions src/glimpse/internal/typecheck.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,96 @@ pub fn expression(
glance.Variable("Nil") ->
Ok(environment.TypeOut(environment, types.NilType))
glance.Variable(name) -> environment.lookup_type_out(environment, name)
glance.BinaryOperator(operator, left, right) ->
binop(environment, operator, left, right)

_ -> {
pprint.debug(expression)
todo
}
}
}

pub fn binop(
environment: Environment,
operator: glance.BinaryOperator,
left: glance.Expression,
right: glance.Expression,
) -> TypeCheckResult {
use environment.TypeOut(environment, left_type) <- result.try(expression(
environment,
left,
))
use environment.TypeOut(environment, right_type) <- result.try(expression(
environment,
right,
))
case operator, left_type, right_type {
glance.LtInt, types.IntType, types.IntType
| glance.LtEqInt, types.IntType, types.IntType
| glance.GtInt, types.IntType, types.IntType
| glance.GtEqInt, types.IntType, types.IntType
| glance.AddInt, types.IntType, types.IntType
| glance.SubInt, types.IntType, types.IntType
| glance.MultInt, types.IntType, types.IntType
| glance.DivInt, types.IntType, types.IntType
| glance.RemainderInt, types.IntType, types.IntType
-> Ok(environment.TypeOut(environment, types.IntType))

glance.LtFloat, types.FloatType, types.FloatType
| glance.LtEqFloat, types.FloatType, types.FloatType
| glance.GtFloat, types.FloatType, types.FloatType
| glance.GtEqFloat, types.FloatType, types.FloatType
| glance.AddFloat, types.FloatType, types.FloatType
| glance.SubFloat, types.FloatType, types.FloatType
| glance.MultFloat, types.FloatType, types.FloatType
| glance.DivFloat, types.FloatType, types.FloatType
-> Ok(environment.TypeOut(environment, types.FloatType))

glance.Concatenate, types.StringType, types.StringType ->
Ok(environment.TypeOut(environment, types.StringType))

glance.LtInt, left, right ->
environment.to_binop_error("<", left, right, "two Ints")
glance.LtFloat, left, right ->
environment.to_binop_error("<.", left, right, "two Floats")
glance.LtEqInt, left, right ->
environment.to_binop_error("<=", left, right, "two Ints")
glance.LtEqFloat, left, right ->
environment.to_binop_error("<=.", left, right, "two Floats")
glance.GtInt, left, right ->
environment.to_binop_error(">", left, right, "two Ints")
glance.GtFloat, left, right ->
environment.to_binop_error(">.", left, right, "two Floats")
glance.GtEqInt, left, right ->
environment.to_binop_error(">=", left, right, "two Ints")
glance.GtEqFloat, left, right ->
environment.to_binop_error(">=.", left, right, "two Floats")
glance.AddInt, left, right ->
environment.to_binop_error("+", left, right, "two Ints")
glance.AddFloat, left, right ->
environment.to_binop_error("+.", left, right, "two Floats")
glance.SubInt, left, right ->
environment.to_binop_error("-", left, right, "two Ints")
glance.SubFloat, left, right ->
environment.to_binop_error("-.", left, right, "two Floats")
glance.MultInt, left, right ->
environment.to_binop_error("*", left, right, "two Ints")
glance.MultFloat, left, right ->
environment.to_binop_error("*.", left, right, "two Floats")
glance.DivInt, left, right ->
environment.to_binop_error("/", left, right, "two Ints")
glance.DivFloat, left, right ->
environment.to_binop_error("/.", left, right, "two Floats")
glance.RemainderInt, left, right ->
environment.to_binop_error("%", left, right, "two Ints")
glance.Concatenate, left, right ->
environment.to_binop_error("<>", left, right, "two Strings")

_, _, _ -> todo as "Most binops not typechecked yet"
}
}

pub fn type_(
environment: Environment,
glance_type: glance.Type,
Expand Down
14 changes: 14 additions & 0 deletions src/glimpse/internal/typecheck/environment.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,17 @@ pub fn lookup_type_out(
lookup_type(environment, name)
|> result.map(TypeOut(environment, _))
}

pub fn to_binop_error(
operator: String,
left: Type,
right: Type,
expected: String,
) -> TypeCheckResult {
Error(error.InvalidBinOp(
operator,
left |> types.to_string,
right |> types.to_string,
expected,
))
}
1 change: 1 addition & 0 deletions src/glimpse/internal/typecheck/types.gleam
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import glance
import gleam/option
import glimpse/error

pub type Type {
NilType
Expand Down
Loading

0 comments on commit d653bbd

Please sign in to comment.