stdlib: Inference engine caught some type errors! Also added some hot garbage.

This commit is contained in:
John 2025-07-18 05:34:03 -04:00
parent 8732cca3f9
commit 0f9044bb3e
9 changed files with 129 additions and 55 deletions

34
stdlib/ffi.cl Normal file
View File

@ -0,0 +1,34 @@
//! Conlang FFI
use super::preamble::*;
type void = ();
#[extern("C")]
/// void free(void *_Nullable ptr);
///
/// Frees a block of memory previously allocated with `malloc`
fn free(ptr: *void);
#[extern("C")]
/// void *malloc(size_t size);
///
/// Allocates a block of uninitialized memory
fn malloc(size: usize) -> *void;
#[extern("C")]
/// void *calloc(size_t n, size_t size);
///
/// Allocates a block of zero-initialized memory
fn calloc(n: usize, size: usize);
#[extern("C")]
/// void *realloc(void *_Nullable ptr, size_t size);
///
/// Reallocates a block of memory to fit `size` bytes
fn realloc(ptr: *void, size: usize) -> *void;
#[extern("C")]
/// void *reallocarray(void *_Nullable ptr, size_t n, size_t size);
///
/// Reallocates a block of memory to fit `n` elements of `size` bytes.
fn reallocarray(ptr: *void, n: usize, size: usize) -> *void;

View File

@ -2,14 +2,19 @@
pub mod preamble {
pub use super::{
io::*,
num::*,
option::Option,
range::{RangeExc, RangeInc},
result::Result,
str::str,
str::*,
};
}
pub mod ffi;
pub mod io;
pub mod num;
pub mod str;
@ -20,5 +25,5 @@ pub mod result;
pub mod range;
#[cfg("test")]
mod test;
// #[cfg("test")]
// mod test;

19
stdlib/std/io.cl Normal file
View File

@ -0,0 +1,19 @@
//! The IO module contains functions for interacting with
//! input and output streams
use super::str::str;
/// Immediately causes program execution to stop
#[builtin = "panic"]
fn panic(..args) -> !;
/// Prints whatever you give it
#[builtin = "print"]
fn print(..args);
/// Prints whatever you give it, followed by a newline
#[builtin = "println"]
fn println(..args);
/// Debug-prints a thing, returning it
#[builtin = "dbg"]
fn dbg(arg) -> _ arg

View File

@ -278,9 +278,9 @@ pub mod ops {
}
impl usize {
pub const MIN: Self = (); // __march_ptr_width_unsigned_min(); // TODO: intrinsics
pub const MAX: Self = (); // __march_ptr_width_unsigned_max(); // TODO: intrinsics
pub const BIT_WIDTH: u32 = (); // __march_ptr_width_bits(); // TODO: intrinsics
pub const MIN: Self = u64::MIN as usize; // __march_ptr_width_unsigned_min(); // TODO: intrinsics
pub const MAX: Self = u64::MAX as usize; // __march_ptr_width_unsigned_max(); // TODO: intrinsics
pub const BIT_WIDTH: u32 = u64::BIT_WIDTH; // __march_ptr_width_bits(); // TODO: intrinsics
pub fn default() -> Self {
0
}
@ -512,9 +512,9 @@ pub mod ops {
}
impl isize {
pub const MIN: Self = (); // __march_ptr_width_signed_min(); // TODO: intrinsics
pub const MAX: Self = (); // __march_ptr_width_signed_max(); // TODO: intrinsics
pub const BIT_WIDTH: u32 = (); // __march_ptr_width_bits(); // TODO: intrinsics
pub const MIN: Self = i64::MIN as isize; // __march_ptr_width_signed_min(); // TODO: intrinsics
pub const MAX: Self = i64::MAX as isize; // __march_ptr_width_signed_max(); // TODO: intrinsics
pub const BIT_WIDTH: u32 = i64::BIT_WIDTH; // __march_ptr_width_bits(); // TODO: intrinsics
pub fn default() -> Self {
0
}

View File

@ -6,24 +6,31 @@ pub enum Option<T> {
None,
}
impl Option {
pub fn is_some(self: &Self) -> bool {
match self {
Some(_) => true,
None => false,
}
}
pub fn is_none(self: &Self) -> bool {
match self {
Some(_) => false,
None => true,
}
}
/// Maps from one option space to another
impl<T> Option<T> {
// pub fn is_some(self) -> bool {
// match self {
// Option::Some(_) => true,
// Option::None() => false,
// }
// }
// pub fn is_none(self: &Self) -> bool {
// match self {
// Option::Some(_) => false,
// Option::None() => true,
// }
// }
// /// Maps from one option space to another
// pub fn map<U>(self: Self, f: fn(T) -> U) -> Option<U> {
// match self {
// Some(value) => Some(f(value)),
// None => None,
// Option::Some(value) => Option::Some(f(value)),
// Option::None() => Option::None(),
// }
// }
// pub fn and_then<U>(self: Self, f: fn(T) -> Option<U>) -> Option<U> {
// match self {
// Option::Some(value) => f(value),
// Option::None() => Option::None(),
// }
// }
}

View File

@ -1,15 +1,17 @@
//! Iterable ranges
/// An Exclusive Range `a .. b` iterates from a to b, excluding b
// #[lang = "range_exc"]
#[lang = "range_exc"]
pub struct RangeExc<T>(T, T)
/// An Inclusive Range `a ..= b` iterates from a to b, including b
// #[lang = "range_inc"]
#[lang = "range_inc"]
pub struct RangeInc<T>(T, T)
impl RangeExc {
fn next<T>(this: &RangeExc) -> T {
(*this).0
}
impl<T> RangeExc<T> {
// fn next(self: &Self) -> T {
// let out = (*self.0);
// (*self).0 += 1;
// out
// }
}

View File

@ -6,29 +6,29 @@ pub enum Result<T, E> {
Err(E),
}
impl Result {
pub fn is_ok(&self) -> bool {
match self {
Ok(_) => true,
Err(_) => false,
}
}
pub fn is_err(&self) -> bool {
match self {
Ok(_) => false,
Err(_) => true,
}
}
/// Maps the value inside the Result::Ok, leaving errors alone.
// pub fn map<U>(self, f: fn(T) -> U) -> Result<U, E> {
// match self {
impl<T, E> Result<T, E> {
// pub fn is_ok(self: &Self) -> bool {
// match *self {
// Ok(_) => true,
// Err(_) => false,
// }
// }
// pub fn is_err(self: &Self) -> bool {
// match *self {
// Ok(_) => false,
// Err(_) => true,
// }
// }
// /// Maps the value inside the Result::Ok, leaving errors alone.
// pub fn map<U>(self: &Self, f: fn(T) -> U) -> Result<U, E> {
// match *self {
// Ok(t) => Ok(f(t)),
// Err(e) => Err(e),
// }
// }
/// Maps the value inside the Result::Err, leaving values alone.
// pub fn map_err<F>(self, f: fn(E) -> F) -> Result<T, F> {
// match self {
// /// Maps the value inside the Result::Err, leaving values alone.
// pub fn map_err<F>(self: &Self, f: fn(E) -> F) -> Result<T, F> {
// match *self {
// Ok(t) => Ok(t),
// Err(e) => Err(f(e)),
// }

View File

@ -1,5 +1,11 @@
//! TODO: give conland a string type
use super::num::u8;
use super::num::{char, u8};
// #[lang = "str"]
#[lang = "str"]
type str = [u8];
#[builtin = "chars"]
fn chars(s: &str) -> [char];
#[builtin = "fmt"]
fn fmt(..args) -> &str;

View File

@ -32,12 +32,13 @@ fn noop () -> bool {
} else break loop if false {
} else break true;
} else break true
}
fn while_else() -> i32 {
let (conditional, pass, fail) = (true, 10, 100 as i32);
while conditional {
pass
pass;
} else {
fail
}
@ -66,7 +67,7 @@ fn if_else() -> i32 {
mod horrible_imports {
mod foo {
use super::{bar::*, baz::*};
struct Foo(&Foo, &Bar)
struct Foo(&Bar, &Baz)
}
mod bar {
use super::{foo::*, baz::*};