Skip to content

Int subtyping #139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/lib/codegen/codegen_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ impl<'a> CodegenContext<'a> {
pub fn lower_type(&mut self, t: &Type, builder: &'a Builder) -> Result<BasicTypeEnum<'a>, ()> {
Ok(match t {
Type::Primitive(PrimitiveType::Int8) => self.context.i8_type().into(),
Type::Primitive(PrimitiveType::Int16) => self.context.i16_type().into(),
Type::Primitive(PrimitiveType::Int32) => self.context.i32_type().into(),
Type::Primitive(PrimitiveType::Int64) => self.context.i64_type().into(),
Type::Primitive(PrimitiveType::Int) => self.context.i64_type().into(),
Type::Primitive(PrimitiveType::Float64) => self.context.f64_type().into(),
Type::Primitive(PrimitiveType::Bool) => self.context.bool_type().into(),
Type::Primitive(PrimitiveType::Char) => self.context.i8_type().into(),
Expand Down Expand Up @@ -767,15 +770,16 @@ impl<'a> CodegenContext<'a> {
) -> Result<BasicValueEnum<'a>, ()> {
Ok(match &lit.kind {
LiteralKind::Number(mut n) => {
let i64_type = self.context.i64_type();
let ty = self.hir.node_types.get(&lit.get_hir_id()).unwrap();
let ty = self.lower_type(ty, builder)?.into_int_type();

let mut negative = false;
if n < 0 {
negative = true;
n = -n;
}

i64_type.const_int((n).try_into().unwrap(), negative).into()
ty.const_int((n).try_into().unwrap(), negative).into()
}
LiteralKind::Float(n) => {
let f64_type = self.context.f64_type();
Expand Down
2 changes: 1 addition & 1 deletion src/lib/diagnostics/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ impl Display for DiagnosticKind {
Self::TypeConflict(t1, t2, _in1, _in2) => {
format!(
"Type conflict:\n{:<8}Expected {:?}\n{:<8}But got {:?}",
"", t1, "", t2
"", t2, "", t1
)
}
Self::UnresolvedType(t) => {
Expand Down
6 changes: 5 additions & 1 deletion src/lib/infer/constraint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ impl<'a> ConstraintContext<'a> {

// Fix the current sig if some types were still unknown
self.envs.amend_current_sig(&new_f_sig);
println!("NEW F SIG {:#?}", new_f_sig);

// We restore the scope here
if !self.envs.set_current_fn(old_f) {
Expand Down Expand Up @@ -421,6 +422,7 @@ impl<'a, 'ar> Visitor<'a> for ConstraintContext<'ar> {

fn visit_function_decl(&mut self, f: &'a FunctionDecl) {
self.envs.apply_args_type(f);
println!("VISITING FUNCTION DECL {:#?}", f);

walk_list!(self, visit_argument_decl, &f.arguments);

Expand All @@ -442,6 +444,8 @@ impl<'a, 'ar> Visitor<'a> for ConstraintContext<'ar> {
)),
);

println!("FN DECL {:#?}", self.envs.get_type(&f.hir_id));

self.envs.set_type_eq(&f.name.hir_id, &f.hir_id);

self.add_tmp_resolution_to_current_fn(&f.name.hir_id, &f.hir_id);
Expand Down Expand Up @@ -724,7 +728,7 @@ impl<'a, 'ar> Visitor<'a> for ConstraintContext<'ar> {

fn visit_literal(&mut self, lit: &Literal) {
let t = match &lit.kind {
LiteralKind::Number(_n) => Type::Primitive(PrimitiveType::Int64),
LiteralKind::Number(_n) => Type::Primitive(PrimitiveType::Int), // not a real type
LiteralKind::Float(_f) => Type::Primitive(PrimitiveType::Float64),
LiteralKind::String(_s) => Type::Primitive(PrimitiveType::String),
LiteralKind::Bool(_b) => Type::Primitive(PrimitiveType::Bool),
Expand Down
4 changes: 4 additions & 0 deletions src/lib/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ pub fn infer(
parsing_ctx: &mut ParsingCtx,
config: &Config,
) -> Result<crate::hir::Root, Diagnostic> {
if config.show_state {
super::hir::hir_printer::print(root);
}

let (tmp_resolutions, diags) = constraint::solve(root);

parsing_ctx.diagnostics.append(diags);
Expand Down
36 changes: 10 additions & 26 deletions src/lib/infer/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ impl Envs {
));
}
}
// generic Int subtyping
(Type::Primitive(src_prim), Some(Type::Primitive(PrimitiveType::Int)))
if src_prim.is_concrete_int() =>
{
error!(
"Replacing hir_id {:?} type {:?} with {:?}",
dest, previous, src
);
}
(src, Some(previous)) if !src.eq(&previous) => {
if previous.is_solved() && src.is_solved() {
self.diagnostics.push_error(Diagnostic::new_type_conflict(
Expand Down Expand Up @@ -107,33 +116,8 @@ impl Envs {
}

let src_t = src_t_opt?.clone();
let previous = self.set_type_alone(dest, &src_t);

match (src_t.clone(), previous.clone()) {
(Type::Func(src_f), Some(Type::Func(prev_f))) if !src_f.eq(&prev_f) => {
if prev_f.is_solved() && src_f.is_solved() {
self.diagnostics.push_error(Diagnostic::new_type_conflict(
self.spans.get(src).unwrap().clone().into(),
previous.clone().unwrap(),
src_t.clone(),
previous.unwrap(),
src_t.clone(),
));
}
}
(src_t, Some(previous)) if !src_t.eq(&previous) => {
if previous.is_solved() && src_t.is_solved() {
self.diagnostics.push_error(Diagnostic::new_type_conflict(
self.spans.get(src).unwrap().clone().into(),
previous.clone(),
src_t.clone(),
previous,
src_t,
));
}
}
_ => (),
}
self.set_type(dest, &src_t);

Some(())
}
Expand Down
15 changes: 13 additions & 2 deletions src/lib/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ lazy_static! {
"/std/src/vec.rk".into(),
include_str!("../../../std/src/vec.rk"),
);
m.insert(
"/std/src/socket.rk".into(),
include_str!("../../../std/src/socket.rk"),
);
m
};
}
Expand Down Expand Up @@ -242,7 +246,7 @@ pub fn parse_root(input: Parser) -> Res<Parser, Root> {

pub fn parse_mod(input: Parser) -> Res<Parser, Mod> {
map(
many1(terminated(parse_top_level, many1(line_ending))),
terminated(many1(terminated(parse_top_level, many1(line_ending))), eof),
Mod::new,
)(input)
}
Expand Down Expand Up @@ -289,7 +293,9 @@ pub fn parse_mod_decl(input: Parser) -> Res<Parser, (Identifier, Mod)> {
.files
.insert(new_ctx.current_file_path().clone(), file.clone());

let new_parser = Parser::new_extra(&file.content, new_ctx);
let content = file.content.clone();

let new_parser = Parser::new_extra(&content, new_ctx);

use nom::Finish;

Expand All @@ -305,6 +311,8 @@ pub fn parse_mod_decl(input: Parser) -> Res<Parser, (Identifier, Mod)> {
input.extra.identities.extend(new_parser.extra.identities);
input.extra.files.extend(new_parser.extra.files);

println!("ERROR: {:#?}", err);

return Err(nom::Err::Error(VerboseError::from_external_error(
input,
ErrorKind::Fail,
Expand Down Expand Up @@ -1178,6 +1186,9 @@ pub fn parse_type(input: Parser) -> Res<Parser, Type> {
alt((
map(tag("Bool"), |_| PrimitiveType::Bool),
map(tag("Int64"), |_| PrimitiveType::Int64),
map(tag("Int32"), |_| PrimitiveType::Int32),
map(tag("Int16"), |_| PrimitiveType::Int16),
map(tag("Int8"), |_| PrimitiveType::Int8),
map(tag("Float64"), |_| PrimitiveType::Float64),
map(tag("String"), |_| PrimitiveType::String),
map(tag("Char"), |_| PrimitiveType::Char),
Expand Down
6 changes: 3 additions & 3 deletions src/lib/ty/func_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl FuncType {
.unzip();

if !ret.is_forall() {
warn!("Trying to apply type to a not forall");
warn!("Trying to apply type to a not forall: {:#?}", ret);
}

// FIXME: must remplace all occurences of ret
Expand All @@ -154,7 +154,7 @@ impl FuncType {
.enumerate()
.filter_map(|(i, arg_t)| -> Option<(Type, Type)> {
if !arg_t.is_forall() {
warn!("Trying to apply type to a not forall");
warn!("Trying to apply type to a not forall: {:#?}", arg_t);

return None;
}
Expand All @@ -168,7 +168,7 @@ impl FuncType {

if let Some(t) = ret {
if !t.is_forall() {
warn!("Trying to apply type to a not forall");
warn!("Trying to apply type to a not forall: {:#?}", t);
}

// FIXME: must remplace all occurences of ret
Expand Down
11 changes: 11 additions & 0 deletions src/lib/ty/primitive_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub enum PrimitiveType {
Int16,
Int32,
Int64,
Int, // not a real type, default to Int64
Float64,
String,
Array(Box<Type>, usize),
Expand All @@ -31,6 +32,7 @@ impl PrimitiveType {
Self::Int16 => "Int16".to_string(),
Self::Int32 => "Int32".to_string(),
Self::Int64 => "Int64".to_string(),
Self::Int => "Int64".to_string(),
Self::Float64 => "Float64".to_string(),
Self::String => "String".to_string(),
Self::Array(t, _size) => format!("[{}]", t.get_name()),
Expand All @@ -46,6 +48,7 @@ impl PrimitiveType {
"Int16" => Some(Self::Int16),
"Int32" => Some(Self::Int32),
"Int64" => Some(Self::Int64),
"Int" => Some(Self::Int64),
"Float64" => Some(Self::Float64),
"String" => Some(Self::String),
"Char" => Some(Self::Char),
Expand Down Expand Up @@ -73,6 +76,14 @@ impl PrimitiveType {
matches!(self, PrimitiveType::Int64)
}

pub fn is_int(&self) -> bool {
matches!(self, PrimitiveType::Int)
}

pub fn is_concrete_int(&self) -> bool {
self.is_int8() || self.is_int16() || self.is_int32() || self.is_int64()
}

pub fn is_float64(&self) -> bool {
matches!(self, PrimitiveType::Float64)
}
Expand Down
2 changes: 1 addition & 1 deletion std/src/functor.rk
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ map: f, arr ->
i = i + 1
arr2

foreach: f arr ->
foreach: f, arr ->
let i = 0
while i < (~Len arr arr)
f arr[i]
Expand Down
6 changes: 3 additions & 3 deletions std/src/helpers.rk
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ infix >> 2
infix << 2
infix |> 1

>>: x y -> y
<<: x y -> x
|>: k l -> l k
>>: x, y -> y
<<: x, y -> x
|>: k, l -> l k

_shutup_warnings: x ->
1 >> 1
Expand Down
1 change: 1 addition & 0 deletions std/src/lib.rk
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ mod functor
mod clone
mod vec
mod helpers
mod socket

mod prelude
1 change: 1 addition & 0 deletions std/src/prelude.rk
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ use super::clone::(*)
use super::fs::(*)
use super::vec::(*)
use super::helpers::(*)
use super::socket::(*)