Skip to content

Commit

Permalink
Impl default and inferred integers
Browse files Browse the repository at this point in the history
  • Loading branch information
Amejonah1200 committed Sep 13, 2023
1 parent 04098dd commit eceef1c
Show file tree
Hide file tree
Showing 11 changed files with 324 additions and 110 deletions.
68 changes: 68 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ chumsky = { git = "https://github.com/zesterer/chumsky.git", rev = "56762fe5c965
] }
walkdir = { git = "https://github.com/APLanguage/walkdir.git" }
# chumsky = { version = "1.0.0-alpha.4", features = ["label"] }
num = "0.4.1"
num-traits = "0.2"
# num-derive = "0.3"
regex = "1.9"
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ fn main() {
// }
return;
}
for (file_id, errs) in resolve_and_typecheck_functions(&mut workspace, dependency_id) {
for (file_id, errs) in resolve_and_typecheck_functions(&rodeo, &mut workspace, dependency_id) {
is_errors = true;
let file = workspace.project().files.file_by_id(file_id).unwrap();
// Generate & choose some colours for each of our elements
Expand Down
2 changes: 1 addition & 1 deletion src/parsing/parsers/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ where EP: TokenParser<'a, I, Expression> + Clone + 'a {
choice((
just(Token::Number)
.map_with_state(|_, span: SimpleSpan, input: &mut ParserState<'a>| {
parse_complex_number(input.slice(span.into()).unwrap())
parse_complex_number(input.rodeo, input.slice(span.into()).unwrap())
})
.map(Expression::Number)
.boxed(),
Expand Down
67 changes: 34 additions & 33 deletions src/parsing/parsers/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ use std::{
sync::OnceLock,
};

use either::Either;
use lasso::Rodeo;
use num::BigInt;
use num_traits::{Num, PrimInt};
use regex::Regex;

use crate::typing::{FloatWidth, IntegerWidth};

#[derive(Debug, PartialEq, Clone)]
pub enum LiteralWidthError {
NotSupported(u64),
Expand All @@ -18,11 +23,7 @@ pub enum NumberLiteral {
Unsigned(u64, LiteralWidth),
Signed(i64, LiteralWidth),
Float(f64, LiteralWidth),
Inferred {
unsigned: Option<u64>,
signed: Option<i64>,
float: Option<f64>,
},
Inferred(Either<BigInt, ()>),
}
impl NumberLiteral {
fn inferred_of_u64(input: u64) -> NumberLiteral {
Expand Down Expand Up @@ -86,6 +87,26 @@ impl TryFrom<u64> for LiteralWidth {
}
}

impl From<IntegerWidth> for LiteralWidth {
fn from(value: IntegerWidth) -> Self {
match value {
IntegerWidth::_8 => LiteralWidth::_8,
IntegerWidth::_16 => LiteralWidth::_16,
IntegerWidth::_32 => LiteralWidth::_32,
IntegerWidth::_64 => LiteralWidth::_64,
}
}
}

impl From<FloatWidth> for LiteralWidth {
fn from(value: FloatWidth) -> Self {
match value {
FloatWidth::_32 => LiteralWidth::_32,
FloatWidth::_64 => LiteralWidth::_64,
}
}
}

pub type LiteralWidthResult = Result<LiteralWidth, LiteralWidthError>;
pub type NumberLiteralResult = Result<NumberLiteral, NumberLiteralError>;

Expand All @@ -110,7 +131,7 @@ where T: PrimInt {

static NUMBER_REGEX: OnceLock<Regex> = OnceLock::new();

pub fn parse_complex_number(input: &str) -> NumberLiteralResult {
pub fn parse_complex_number(_rodeo: &mut Rodeo, input: &str) -> NumberLiteralResult {
let Some(captures) = NUMBER_REGEX
.get_or_init(|| Regex::new(r"^(0x|0b|0o)?(\w+?(?:\.\w+?)*)?(?:([uif])(\d+))?$").unwrap())
.captures(input)
Expand Down Expand Up @@ -148,40 +169,20 @@ pub fn parse_complex_number(input: &str) -> NumberLiteralResult {
)
});
// ((is_negative, has_minus), (radix, value, num_type_width))
// for the time being, the negative part could be handled with this parser later
// TODO: for the time being, the negative part could be handled with this parser later
let is_negative = false;
let has_minus = false;
// let has_minus = false;

let mut number_part = value.replace('_', "");
if is_negative {
number_part = "-".to_owned() + &number_part
}
if num_type_width.is_none() {
let unsigned = if !has_minus {
parse_number::<u64>(&number_part, radix).ok()
} else {
None
};
let signed = parse_number::<i64>(&number_part, radix).ok();
let float = if radix == 10 {
number_part.parse::<f64>().ok()
} else {
None
};
return match (unsigned.is_some() as u8) + (signed.is_some() as u8) + (float.is_some() as u8)
{
0 => Err(NumberLiteralError::CannotInfer),
1 => Ok(unsigned
.map(NumberLiteral::inferred_of_u64)
.or_else(|| signed.map(NumberLiteral::inferred_of_i64))
.or_else(|| float.map(NumberLiteral::inferred_of_f64))
.unwrap()),
_ => Ok(NumberLiteral::Inferred {
unsigned,
signed,
float,
}),
};
return Ok(NumberLiteral::Inferred(
BigInt::parse_bytes(number_part.as_bytes(), radix)
.map(Either::Left)
.unwrap_or(Either::Right(())),
));
};
let (num_type, width) = num_type_width.unwrap();
let width = LiteralWidth::try_from(width).map_err(num_type.width_error())?;
Expand Down
41 changes: 26 additions & 15 deletions src/project/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
use chumsky::span::SimpleSpan;
use either::Either;
use itertools::Itertools;
use lasso::{Spur, Rodeo};
use lasso::{Rodeo, Spur};
use slotmap::{new_key_type, SlotMap};

use crate::parsing::ast::declarations::{Function, Struct, UseDeclaration};
Expand Down Expand Up @@ -141,21 +141,26 @@ impl TypeRegistry {
.unwrap()
}

pub fn display_type(&self, rodeo: &Rodeo, dependencies: &Dependencies, type_id: TypeId) -> String {
pub fn display_type(
&self,
rodeo: &Rodeo,
dependencies: &Dependencies,
type_id: TypeId,
) -> String {
self.get(type_id).map_or_else(
|| "?".to_string(),
|ty| match ty {
Type::PrimitiveType(ty) => Self::display_primitive_type(*ty).to_string(),
Type::Data(dep, struct_id) => {
let dependency_info = dependencies.get_dependency(*dep).unwrap();
let project_name = rodeo.resolve(&dependency_info.name);
let struct_path = &dependency_info
.project
.struct_path(*struct_id)
.map(|s| rodeo.resolve(&s))
.join("::");
let struct_path = &dependency_info
.project
.struct_path(*struct_id)
.map(|s| rodeo.resolve(&s))
.join("::");
format!("({project_name}) {struct_path}")
},
}
Type::Array { ty: _, size: _ } => todo!("Type::Array"),
Type::Function {
parameters: _,
Expand Down Expand Up @@ -237,34 +242,40 @@ impl Workspace {
self._project
}

pub fn resolver_by_scope(
&self,
pub fn resolver_by_scope<'a>(
&'a self,
rodeo: &'a Rodeo,
dependency_id: DependencyId,
scope_id: ScopeId,
) -> FileScopedNameResolver<'_> {
) -> FileScopedNameResolver<'a> {
FileScopedNameResolver::new_with_scope(
&self.dependencies,
self.type_registery.clone(),
dependency_id,
scope_id,
rodeo,
)
}

pub fn resolver_by_file(
&self,
pub fn resolver_by_file<'a>(
&'a self,
rodeo: &'a Rodeo,
dependency_id: DependencyId,
file_id: FileId,
) -> FileScopedNameResolver<'_> {
) -> FileScopedNameResolver<'a> {
FileScopedNameResolver::new_with_file(
&self.dependencies,
self.type_registery.clone(),
dependency_id,
file_id,
rodeo,
)
}

pub fn display_type(&self, rodeo: &Rodeo, ty: TypeId) -> String {
self.type_registery.borrow().display_type(rodeo, &self.dependencies, ty)
self.type_registery
.borrow()
.display_type(rodeo, &self.dependencies, ty)
}
}

Expand Down
32 changes: 28 additions & 4 deletions src/resolution/fir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ use slotmap::{new_key_type, SlotMap};

use crate::{
parsing::{
self,
ast::expressions::StringLiteral,
parsers::number::NumberLiteralResult,
parsers::{number::NumberLiteralError, self},
tokenizer::{Operation, OperationGroup},
Infoable, Infoed, Spanned,
},
project::{DependencyId, FunctionId, StructId, VariableId},
typing::TypeId,
typing::{FloatWidth, IntegerWidth, TypeId},
};

new_key_type! { pub struct LocalVarId; }
Expand Down Expand Up @@ -43,7 +44,7 @@ pub enum CallKind {
pub enum AssignableTarget {
Var(TypeId, VariableType),
StructField(TypeId, DependencyId, StructId, usize),
Unnassignable
Unnassignable,
}

#[derive(Debug, PartialEq)]
Expand All @@ -53,7 +54,7 @@ pub enum Expression {
then: Box<Infoed<Expression>>,
other: Box<Infoed<Expression>>,
},
Number(NumberLiteralResult),
Number(Result<NumberLiteral, NumberLiteralError>),
StringLiteral(StringLiteral),
Bool(bool),
CallChain {
Expand Down Expand Up @@ -123,3 +124,26 @@ impl Infoable for Expression {
impl Infoable for CallKind {
type Info = TypeId;
}

#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum NumberLiteral {
Float(f64, FloatWidth),
Integer(bool, i128, IntegerWidth),
}

impl From<parsing::parsers::number::NumberLiteral> for NumberLiteral {
fn from(value: parsing::parsers::number::NumberLiteral) -> Self {
match value {
parsers::number::NumberLiteral::Unsigned(n, w) => {
NumberLiteral::Integer(false, n as i128, w.into())
}
parsers::number::NumberLiteral::Signed(n, w) => {
NumberLiteral::Integer(true, n as i128, w.into())
}
parsers::number::NumberLiteral::Float(n, w) => NumberLiteral::Float(n, w.into()),
parsers::number::NumberLiteral::Inferred(_) => {
panic!("Cannot transform inferred number")
}
}
}
}
Loading

0 comments on commit eceef1c

Please sign in to comment.