Add types to number-literals
This commit is contained in:
parent
211cca50b8
commit
5b46e973d4
@ -45,9 +45,12 @@ Currently missing big features (TODOs) are:
|
||||
- ~~Built-in Int/Float division and modulo~~ (DONE)
|
||||
- ~~Loops~~ (DONE)
|
||||
- ~~Intrinsic functions~~ (DONE)
|
||||
- ~~Ability to specify types in literals~~ (DONE)
|
||||
- Debug Information (PARTIALLY DONE)
|
||||
- Ability to specify types in literals and variable definitions
|
||||
- Not-Unary
|
||||
- Importing types from other modules
|
||||
- Importable binops?
|
||||
- Ability to specify types in variable definitions
|
||||
|
||||
Big features that I want later but are not necessary:
|
||||
- Associated functions
|
||||
|
@ -45,6 +45,28 @@ pub enum Literal {
|
||||
Bool(bool),
|
||||
String(String),
|
||||
Char(char),
|
||||
Specific(SpecificLiteral),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SpecificLiteral {
|
||||
I8(i8),
|
||||
I16(i16),
|
||||
I32(i32),
|
||||
I64(i64),
|
||||
I128(i128),
|
||||
U8(u8),
|
||||
U16(u16),
|
||||
U32(u32),
|
||||
U64(u64),
|
||||
U128(u128),
|
||||
F16(f32),
|
||||
F32(f32),
|
||||
F32B(f32),
|
||||
F64(f64),
|
||||
F80(f64),
|
||||
F128(f64),
|
||||
F128PPC(f64),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -96,6 +96,46 @@ impl Parse for UnaryOperator {
|
||||
}
|
||||
}
|
||||
|
||||
fn specific_int_lit(value: u128, stream: &mut TokenStream) -> Result<Expression, Error> {
|
||||
use ExpressionKind as Kind;
|
||||
|
||||
let specific_lit = if let Ok(ty) = stream.parse::<Type>() {
|
||||
Some(match ty.0 {
|
||||
TypeKind::I8 => SpecificLiteral::I8(value as i8),
|
||||
TypeKind::I16 => SpecificLiteral::I16(value as i16),
|
||||
TypeKind::I32 => SpecificLiteral::I32(value as i32),
|
||||
TypeKind::I64 => SpecificLiteral::I64(value as i64),
|
||||
TypeKind::I128 => SpecificLiteral::I128(value as i128),
|
||||
TypeKind::U8 => SpecificLiteral::U8(value as u8),
|
||||
TypeKind::U16 => SpecificLiteral::U16(value as u16),
|
||||
TypeKind::U32 => SpecificLiteral::U32(value as u32),
|
||||
TypeKind::U64 => SpecificLiteral::U64(value as u64),
|
||||
TypeKind::U128 => SpecificLiteral::U128(value as u128),
|
||||
TypeKind::F16 => SpecificLiteral::F16(value as f32),
|
||||
TypeKind::F32 => SpecificLiteral::F32(value as f32),
|
||||
TypeKind::F32B => SpecificLiteral::F32B(value as f32),
|
||||
TypeKind::F64 => SpecificLiteral::F64(value as f64),
|
||||
TypeKind::F128 => SpecificLiteral::F128(value as f64),
|
||||
TypeKind::F80 => SpecificLiteral::F80(value as f64),
|
||||
TypeKind::F128PPC => SpecificLiteral::F128PPC(value as f64),
|
||||
_ => return Err(stream.expected_err("integer-compatible type")?),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok(if let Some(lit) = specific_lit {
|
||||
Expression(
|
||||
Kind::Literal(Literal::Specific(lit)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
} else {
|
||||
Expression(
|
||||
Kind::Literal(Literal::Integer(value)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PrimaryExpression(Expression);
|
||||
|
||||
@ -154,32 +194,26 @@ impl Parse for PrimaryExpression {
|
||||
}
|
||||
}
|
||||
Token::BinaryValue(v) => {
|
||||
stream.next(); // Consume octal
|
||||
Expression(
|
||||
Kind::Literal(Literal::Integer(
|
||||
u128::from_str_radix(&v, 2).expect("Binary is not parseable as u128!"),
|
||||
)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
stream.next(); // Consume binary
|
||||
specific_int_lit(
|
||||
u128::from_str_radix(&v, 2).expect("Binary is not parseable as u128!"),
|
||||
&mut stream,
|
||||
)?
|
||||
}
|
||||
Token::OctalValue(v) => {
|
||||
stream.next(); // Consume octal
|
||||
Expression(
|
||||
Kind::Literal(Literal::Integer(
|
||||
u128::from_str_radix(&v, 8).expect("Octal is not parseable as u128!"),
|
||||
)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
specific_int_lit(
|
||||
u128::from_str_radix(&v, 8).expect("Octal is not parseable as u128!"),
|
||||
&mut stream,
|
||||
)?
|
||||
}
|
||||
Token::HexadecimalValue(v) => {
|
||||
stream.next(); // Consume hexadecimal
|
||||
Expression(
|
||||
Kind::Literal(Literal::Integer(
|
||||
u128::from_str_radix(&v, 16)
|
||||
.expect("Hexadecimal is not parseable as u128!"),
|
||||
)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
specific_int_lit(
|
||||
u128::from_str_radix(&v, 16)
|
||||
.expect("Hexadecimal is not parseable as u128!"),
|
||||
&mut stream,
|
||||
)?
|
||||
}
|
||||
Token::DecimalValue(v) => {
|
||||
stream.next(); // Consume decimal
|
||||
@ -189,22 +223,41 @@ impl Parse for PrimaryExpression {
|
||||
stream.next(); // Consume dot
|
||||
stream.next(); // Consume fractional
|
||||
|
||||
Expression(
|
||||
Kind::Literal(Literal::Decimal(
|
||||
format!("{}.{}", v, fractional)
|
||||
.parse()
|
||||
.expect("Decimal is not parseable as f64!"),
|
||||
)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
let value = format!("{}.{}", v, fractional)
|
||||
.parse()
|
||||
.expect("Decimal is not parseable as f64!");
|
||||
|
||||
let specific_lit = if let Ok(ty) = stream.parse::<Type>() {
|
||||
Some(match ty.0 {
|
||||
TypeKind::F16 => SpecificLiteral::F16(value as f32),
|
||||
TypeKind::F32B => SpecificLiteral::F32B(value as f32),
|
||||
TypeKind::F32 => SpecificLiteral::F32(value as f32),
|
||||
TypeKind::F64 => SpecificLiteral::F64(value),
|
||||
TypeKind::F80 => SpecificLiteral::F80(value),
|
||||
TypeKind::F128 => SpecificLiteral::F128(value),
|
||||
TypeKind::F128PPC => SpecificLiteral::F128PPC(value),
|
||||
_ => return Err(stream.expected_err("float-compatible type")?),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(lit) = specific_lit {
|
||||
Expression(
|
||||
Kind::Literal(Literal::Specific(lit)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
} else {
|
||||
Expression(
|
||||
Kind::Literal(Literal::Decimal(value)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Expression(
|
||||
Kind::Literal(Literal::Integer(
|
||||
u128::from_str_radix(&v, 10)
|
||||
.expect("Integer is not parseable as u128!"),
|
||||
)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
specific_int_lit(
|
||||
u128::from_str_radix(&v, 10)
|
||||
.expect("Integer is not parseable as u128!"),
|
||||
&mut stream,
|
||||
)?
|
||||
}
|
||||
}
|
||||
Token::StringLit(v) => {
|
||||
|
@ -8,6 +8,8 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
use super::TypeKind;
|
||||
|
||||
impl mir::Context {
|
||||
pub fn from(modules: Vec<mir::Module>, base: PathBuf) -> mir::Context {
|
||||
let mut map = ModuleMap::new();
|
||||
@ -417,6 +419,25 @@ impl ast::Literal {
|
||||
ast::Literal::String(val) => mir::Literal::String(val.clone()),
|
||||
ast::Literal::Decimal(v) => mir::Literal::Vague(mir::VagueLiteral::Decimal(*v)),
|
||||
ast::Literal::Char(inner) => mir::Literal::Char(*inner),
|
||||
ast::Literal::Specific(specific_literal) => match specific_literal {
|
||||
ast::SpecificLiteral::I8(val) => mir::Literal::I8(*val),
|
||||
ast::SpecificLiteral::I16(val) => mir::Literal::I16(*val),
|
||||
ast::SpecificLiteral::I32(val) => mir::Literal::I32(*val),
|
||||
ast::SpecificLiteral::I64(val) => mir::Literal::I64(*val),
|
||||
ast::SpecificLiteral::I128(val) => mir::Literal::I128(*val),
|
||||
ast::SpecificLiteral::U8(val) => mir::Literal::U8(*val),
|
||||
ast::SpecificLiteral::U16(val) => mir::Literal::U16(*val),
|
||||
ast::SpecificLiteral::U32(val) => mir::Literal::U32(*val),
|
||||
ast::SpecificLiteral::U64(val) => mir::Literal::U64(*val),
|
||||
ast::SpecificLiteral::U128(val) => mir::Literal::U128(*val),
|
||||
ast::SpecificLiteral::F16(val) => mir::Literal::F16(*val),
|
||||
ast::SpecificLiteral::F32(val) => mir::Literal::F32(*val),
|
||||
ast::SpecificLiteral::F32B(val) => mir::Literal::F32B(*val),
|
||||
ast::SpecificLiteral::F64(val) => mir::Literal::F64(*val),
|
||||
ast::SpecificLiteral::F80(val) => mir::Literal::F80(*val),
|
||||
ast::SpecificLiteral::F128(val) => mir::Literal::F128(*val),
|
||||
ast::SpecificLiteral::F128PPC(val) => mir::Literal::F128PPC(*val),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -326,7 +326,15 @@ impl Expression {
|
||||
{
|
||||
Ok(binop)
|
||||
} else {
|
||||
let typeref = lhs_ref.narrow(&rhs_ref).unwrap();
|
||||
let typeref = state.or_else(
|
||||
lhs_ref.narrow(&rhs_ref).ok_or(ErrorKind::InvalidBinop(
|
||||
*op,
|
||||
lhs_ref.resolve_deep().unwrap(),
|
||||
rhs_ref.resolve_deep().unwrap(),
|
||||
)),
|
||||
type_refs.from_type(&Vague(Unknown)).unwrap(),
|
||||
self.1,
|
||||
);
|
||||
Ok(type_refs
|
||||
.from_type(
|
||||
&typeref
|
||||
|
Loading…
Reference in New Issue
Block a user