Compare commits

..

6 Commits

19 changed files with 427 additions and 35 deletions

View File

@ -38,6 +38,7 @@ Currently missing relevant features (TODOs) are:
- ~~Extern functions~~ (DONE) - ~~Extern functions~~ (DONE)
- ~~Strings~~ (DONE) - ~~Strings~~ (DONE)
- Loops - Loops
- Debug Information
### Why "Reid" ### Why "Reid"

View File

@ -14,7 +14,7 @@
BINARY="$(echo $1 | cut -d'.' -f1)"".out" BINARY="$(echo $1 | cut -d'.' -f1)"".out"
make clean SRC=$1 && make SRC=$1 && echo "" make clean SRC=$1 ; make SRC=$1 && echo ""
$BINARY ; echo "Return value: ""$?" $BINARY ; echo "Return value: ""$?"

View File

@ -5,12 +5,15 @@ use std::{cell::RefCell, rc::Rc};
use crate::{ use crate::{
BlockData, ConstValue, FunctionData, Instr, InstructionData, ModuleData, TerminatorKind, Type, BlockData, ConstValue, FunctionData, Instr, InstructionData, ModuleData, TerminatorKind, Type,
util::match_types, TypeData, util::match_types,
}; };
#[derive(Clone, Hash, Copy, PartialEq, Eq)] #[derive(Clone, Hash, Copy, PartialEq, Eq)]
pub struct ModuleValue(pub(crate) usize); pub struct ModuleValue(pub(crate) usize);
#[derive(Clone, Hash, Copy, PartialEq, Eq)]
pub struct TypeValue(pub(crate) ModuleValue, pub(crate) usize);
#[derive(Clone, Hash, Copy, PartialEq, Eq)] #[derive(Clone, Hash, Copy, PartialEq, Eq)]
pub struct FunctionValue(pub(crate) ModuleValue, pub(crate) usize); pub struct FunctionValue(pub(crate) ModuleValue, pub(crate) usize);
@ -25,6 +28,13 @@ pub struct ModuleHolder {
pub(crate) value: ModuleValue, pub(crate) value: ModuleValue,
pub(crate) data: ModuleData, pub(crate) data: ModuleData,
pub(crate) functions: Vec<FunctionHolder>, pub(crate) functions: Vec<FunctionHolder>,
pub(crate) types: Vec<TypeHolder>,
}
#[derive(Clone)]
pub struct TypeHolder {
pub(crate) value: TypeValue,
pub(crate) data: TypeData,
} }
#[derive(Clone)] #[derive(Clone)]
@ -65,6 +75,7 @@ impl Builder {
value, value,
data, data,
functions: Vec::new(), functions: Vec::new(),
types: Vec::new(),
}); });
value value
} }

View File

@ -196,6 +196,10 @@ impl ModuleHolder {
context.context_ref, context.context_ref,
); );
for _ty in &self.types {
todo!("Do something with types!");
}
// Compile the contents // Compile the contents
let mut functions = HashMap::new(); let mut functions = HashMap::new();

View File

@ -263,3 +263,14 @@ pub enum TerminatorKind {
Br(BlockValue), Br(BlockValue),
CondBr(InstructionValue, BlockValue, BlockValue), CondBr(InstructionValue, BlockValue, BlockValue),
} }
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct TypeData {
name: String,
kind: CustomTypeKind,
}
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum CustomTypeKind {
Struct(Vec<Type>),
}

View File

@ -1,4 +1,4 @@
use std::{env, fs, path::PathBuf}; use std::{env, error::Error, fs, path::PathBuf};
use reid::compile; use reid::compile;
use reid_lib::compile::CompileOutput; use reid_lib::compile::CompileOutput;

View File

@ -163,6 +163,7 @@ fn main() {
name: "test module".to_owned(), name: "test module".to_owned(),
imports: vec![], imports: vec![],
functions: vec![fibonacci, main], functions: vec![fibonacci, main],
typedefs: Vec::new(),
path: None, path: None,
is_main: true, is_main: true,
}], }],

View File

@ -26,6 +26,7 @@ pub enum TypeKind {
U128, U128,
String, String,
Array(Box<TypeKind>, u64), Array(Box<TypeKind>, u64),
Custom(String),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -43,11 +44,13 @@ pub enum ExpressionKind {
VariableName(String), VariableName(String),
Literal(Literal), Literal(Literal),
Array(Vec<Expression>), Array(Vec<Expression>),
Index(Box<Expression>, u64), ArrayIndex(Box<Expression>, u64),
StructIndex(Box<Expression>, String),
Binop(BinaryOperator, Box<Expression>, Box<Expression>), Binop(BinaryOperator, Box<Expression>, Box<Expression>),
FunctionCall(Box<FunctionCallExpression>), FunctionCall(Box<FunctionCallExpression>),
BlockExpr(Box<Block>), BlockExpr(Box<Block>),
IfExpr(Box<IfExpression>), IfExpr(Box<IfExpression>),
StructExpression(StructExpression),
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -129,6 +132,12 @@ pub enum ReturnType {
Hard, Hard,
} }
#[derive(Debug, Clone)]
pub struct StructExpression {
name: String,
fields: Vec<(String, Expression)>,
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Block( pub struct Block(
pub Vec<BlockLevelStatement>, pub Vec<BlockLevelStatement>,
@ -142,7 +151,8 @@ pub struct VariableReference(pub VariableReferenceKind, pub TokenRange);
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum VariableReferenceKind { pub enum VariableReferenceKind {
Name(String, TokenRange), Name(String, TokenRange),
Index(Box<VariableReference>, u64), ArrayIndex(Box<VariableReference>, u64),
StructIndex(Box<VariableReference>, String),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -157,11 +167,31 @@ pub enum BlockLevelStatement {
Return(ReturnType, Expression), Return(ReturnType, Expression),
} }
#[derive(Debug)]
pub struct TypeDefinition {
name: String,
kind: TypeDefinitionKind,
range: TokenRange,
}
#[derive(Debug)]
pub enum TypeDefinitionKind {
Struct(Vec<StructDefinitionField>),
}
#[derive(Debug)]
pub struct StructDefinitionField {
name: String,
ty: Type,
range: TokenRange,
}
#[derive(Debug)] #[derive(Debug)]
pub enum TopLevelStatement { pub enum TopLevelStatement {
Import(ImportStatement), Import(ImportStatement),
ExternFunction(FunctionSignature), ExternFunction(FunctionSignature),
FunctionDefinition(FunctionDefinition), FunctionDefinition(FunctionDefinition),
TypeDefinition(TypeDefinition),
} }
#[derive(Debug)] #[derive(Debug)]

View File

@ -76,10 +76,24 @@ impl Parse for PrimaryExpression {
) )
} else if let Ok(ifexpr) = stream.parse() { } else if let Ok(ifexpr) = stream.parse() {
Expression(Kind::IfExpr(Box::new(ifexpr)), stream.get_range().unwrap()) Expression(Kind::IfExpr(Box::new(ifexpr)), stream.get_range().unwrap())
} else if let (Some(Token::Identifier(_)), Some(Token::BraceOpen)) =
(stream.peek(), stream.peek2())
{
Expression(
Kind::StructExpression(stream.parse()?),
stream.get_range().unwrap(),
)
} else if let Some(token) = stream.next() { } else if let Some(token) = stream.next() {
match &token { match &token {
Token::Identifier(v) => { Token::Identifier(v) => {
Expression(Kind::VariableName(v.clone()), stream.get_range().unwrap()) if let Some(Token::BraceOpen) = stream.peek() {
Expression(
Kind::StructExpression(stream.parse()?),
stream.get_range().unwrap(),
)
} else {
Expression(Kind::VariableName(v.clone()), stream.get_range().unwrap())
}
} }
Token::DecimalValue(v) => Expression( Token::DecimalValue(v) => Expression(
Kind::Literal(Literal::Number(*v)), Kind::Literal(Literal::Number(*v)),
@ -120,11 +134,21 @@ impl Parse for PrimaryExpression {
Err(stream.expected_err("expression")?)? Err(stream.expected_err("expression")?)?
}; };
while let Ok(ValueIndex(idx)) = stream.parse() { while let Ok(index) = stream.parse::<ValueIndex>() {
expr = Expression( match index {
ExpressionKind::Index(Box::new(expr), idx), ValueIndex::Array(ArrayValueIndex(idx)) => {
stream.get_range().unwrap(), expr = Expression(
); ExpressionKind::ArrayIndex(Box::new(expr), idx),
stream.get_range().unwrap(),
);
}
ValueIndex::Struct(StructValueIndex(name)) => {
expr = Expression(
ExpressionKind::StructIndex(Box::new(expr), name),
stream.get_range().unwrap(),
);
}
}
} }
Ok(PrimaryExpression(expr)) Ok(PrimaryExpression(expr))
@ -401,9 +425,9 @@ impl Parse for VariableReference {
stream.get_range().unwrap(), stream.get_range().unwrap(),
); );
while let Ok(ValueIndex(idx)) = stream.parse() { while let Ok(ArrayValueIndex(idx)) = stream.parse() {
var_ref = VariableReference( var_ref = VariableReference(
VariableReferenceKind::Index(Box::new(var_ref), idx), VariableReferenceKind::ArrayIndex(Box::new(var_ref), idx),
stream.get_range().unwrap(), stream.get_range().unwrap(),
); );
} }
@ -415,21 +439,101 @@ impl Parse for VariableReference {
} }
} }
#[derive(Debug, Clone, Copy)] impl Parse for StructExpression {
pub struct ValueIndex(u64); fn parse(mut stream: TokenStream) -> Result<Self, Error> {
let Some(Token::Identifier(name)) = stream.next() else {
return Err(stream.expected_err("struct identifier")?);
};
stream.expect(Token::BraceOpen)?;
let named_list = stream.parse::<NamedFieldList<Expression>>()?;
let fields = named_list.0.into_iter().map(|f| (f.0, f.1)).collect();
stream.expect(Token::BraceClose)?;
Ok(StructExpression { name, fields })
}
}
#[derive(Debug)]
pub struct NamedFieldList<T: Parse + std::fmt::Debug>(Vec<NamedField<T>>);
impl<T: Parse + std::fmt::Debug> Parse for NamedFieldList<T> {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
let mut fields = Vec::new();
while let Ok(field) = stream.parse() {
fields.push(field);
match stream.peek() {
Some(Token::Comma) => {
stream.next();
} // Consume comma
Some(Token::BraceClose) => break,
Some(_) | None => Err(stream.expected_err("another field or closing brace")?)?,
}
}
Ok(NamedFieldList(fields))
}
}
#[derive(Debug)]
pub struct NamedField<T: Parse + std::fmt::Debug>(String, T, TokenRange);
impl<T: Parse + std::fmt::Debug> Parse for NamedField<T> {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
let Some(Token::Identifier(field_name)) = stream.next() else {
return Err(stream.expected_err("type name")?);
};
stream.expect(Token::Colon)?;
let value = stream.parse()?;
Ok(NamedField(field_name, value, stream.get_range().unwrap()))
}
}
#[derive(Debug, Clone)]
pub enum ValueIndex {
Array(ArrayValueIndex),
Struct(StructValueIndex),
}
impl Parse for ValueIndex { impl Parse for ValueIndex {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
match stream.peek() {
Some(Token::BracketOpen) => Ok(ValueIndex::Array(stream.parse()?)),
Some(Token::Dot) => Ok(ValueIndex::Struct(stream.parse()?)),
_ => Err(stream.expected_err("value or struct index")?),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct ArrayValueIndex(u64);
impl Parse for ArrayValueIndex {
fn parse(mut stream: TokenStream) -> Result<Self, Error> { fn parse(mut stream: TokenStream) -> Result<Self, Error> {
stream.expect(Token::BracketOpen)?; stream.expect(Token::BracketOpen)?;
if let Some(Token::DecimalValue(idx)) = stream.next() { if let Some(Token::DecimalValue(idx)) = stream.next() {
stream.expect(Token::BracketClose)?; stream.expect(Token::BracketClose)?;
Ok(ValueIndex(idx)) Ok(ArrayValueIndex(idx))
} else { } else {
return Err(stream.expected_err("array index (number)")?); return Err(stream.expected_err("array index (number)")?);
} }
} }
} }
#[derive(Debug, Clone)]
pub struct StructValueIndex(String);
impl Parse for StructValueIndex {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
stream.expect(Token::Dot)?;
if let Some(Token::Identifier(name)) = stream.next() {
Ok(StructValueIndex(name))
} else {
return Err(stream.expected_err("struct index (number)")?);
}
}
}
impl Parse for BlockLevelStatement { impl Parse for BlockLevelStatement {
fn parse(mut stream: TokenStream) -> Result<Self, Error> { fn parse(mut stream: TokenStream) -> Result<Self, Error> {
use BlockLevelStatement as Stmt; use BlockLevelStatement as Stmt;
@ -476,6 +580,33 @@ impl Parse for SetStatement {
} }
} }
#[derive(Debug)]
pub struct StructDefinition(String, Vec<StructDefinitionField>, TokenRange);
impl Parse for StructDefinition {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
stream.expect(Token::Struct)?;
let Some(Token::Identifier(name)) = stream.next() else {
return Err(stream.expected_err("identifier")?);
};
stream.expect(Token::BraceOpen)?;
let named_fields = stream.parse::<NamedFieldList<Type>>()?;
let fields = named_fields
.0
.into_iter()
.map(|f| StructDefinitionField {
name: f.0,
ty: f.1,
range: f.2,
})
.collect();
stream.expect(Token::BraceClose)?;
Ok(StructDefinition(name, fields, stream.get_range().unwrap()))
}
}
impl Parse for TopLevelStatement { impl Parse for TopLevelStatement {
fn parse(mut stream: TokenStream) -> Result<Self, Error> { fn parse(mut stream: TokenStream) -> Result<Self, Error> {
use TopLevelStatement as Stmt; use TopLevelStatement as Stmt;
@ -491,6 +622,14 @@ impl Parse for TopLevelStatement {
Some(Token::FnKeyword) | Some(Token::PubKeyword) => { Some(Token::FnKeyword) | Some(Token::PubKeyword) => {
Stmt::FunctionDefinition(stream.parse()?) Stmt::FunctionDefinition(stream.parse()?)
} }
Some(Token::Struct) => {
let StructDefinition(name, fields, range) = stream.parse::<StructDefinition>()?;
Stmt::TypeDefinition(TypeDefinition {
name,
kind: TypeDefinitionKind::Struct(fields),
range,
})
}
_ => Err(stream.expected_err("import or fn")?)?, _ => Err(stream.expected_err("import or fn")?)?,
}) })
} }

View File

@ -15,6 +15,7 @@ impl ast::Module {
pub fn process(&self) -> mir::Module { pub fn process(&self) -> mir::Module {
let mut imports = Vec::new(); let mut imports = Vec::new();
let mut functions = Vec::new(); let mut functions = Vec::new();
let mut typedefs = Vec::new();
use ast::TopLevelStatement::*; use ast::TopLevelStatement::*;
for stmt in &self.top_level_statements { for stmt in &self.top_level_statements {
@ -62,6 +63,23 @@ impl ast::Module {
}; };
functions.push(def); functions.push(def);
} }
TypeDefinition(ast::TypeDefinition { name, kind, range }) => {
let def = mir::TypeDefinition {
name: name.clone(),
kind: match kind {
ast::TypeDefinitionKind::Struct(struct_definition_fields) => {
mir::TypeDefinitionKind::Struct(
struct_definition_fields
.iter()
.map(|s| (s.name.clone(), s.ty.clone().into()))
.collect(),
)
}
},
meta: (*range).into(),
};
typedefs.push(def);
}
} }
} }
@ -71,6 +89,7 @@ impl ast::Module {
functions, functions,
path: self.path.clone(), path: self.path.clone(),
is_main: self.is_main, is_main: self.is_main,
typedefs,
} }
} }
} }
@ -151,8 +170,14 @@ impl ast::VariableReferenceKind {
(*range).into(), (*range).into(),
)) ))
} }
ast::VariableReferenceKind::Index(var_ref, idx) => { ast::VariableReferenceKind::ArrayIndex(var_ref, idx) => {
mir::IndexedVariableReferenceKind::Index(Box::new(var_ref.process()), *idx) mir::IndexedVariableReferenceKind::ArrayIndex(Box::new(var_ref.process()), *idx)
}
ast::VariableReferenceKind::StructIndex(var_ref, name) => {
mir::IndexedVariableReferenceKind::StructIndex(
Box::new(var_ref.process()),
name.clone(),
)
} }
} }
} }
@ -193,11 +218,24 @@ impl ast::Expression {
ast::ExpressionKind::Array(expressions) => { ast::ExpressionKind::Array(expressions) => {
mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect()) mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect())
} }
ast::ExpressionKind::Index(expression, idx) => mir::ExprKind::Index( ast::ExpressionKind::ArrayIndex(expression, idx) => mir::ExprKind::ArrayIndex(
Box::new(expression.process()), Box::new(expression.process()),
mir::TypeKind::Vague(mir::VagueType::Unknown), mir::TypeKind::Vague(mir::VagueType::Unknown),
*idx, *idx,
), ),
ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct(
struct_init.name.clone(),
struct_init
.fields
.iter()
.map(|(n, e)| (n.clone(), e.process()))
.collect(),
),
ast::ExpressionKind::StructIndex(expression, name) => mir::ExprKind::StructIndex(
Box::new(expression.process()),
mir::TypeKind::Vague(mir::VagueType::Unknown),
name.clone(),
),
}; };
mir::Expression(kind, self.1.into()) mir::Expression(kind, self.1.into())
@ -249,6 +287,7 @@ impl From<ast::TypeKind> for mir::TypeKind {
mir::TypeKind::Array(Box::new(mir::TypeKind::from(*type_kind.clone())), *length) mir::TypeKind::Array(Box::new(mir::TypeKind::from(*type_kind.clone())), *length)
} }
ast::TypeKind::String => mir::TypeKind::StringPtr, ast::TypeKind::String => mir::TypeKind::StringPtr,
ast::TypeKind::Custom(_) => todo!("Add processing for custom types"),
} }
} }
} }

View File

@ -173,7 +173,7 @@ impl IndexedVariableReference {
.get(name) .get(name)
.cloned() .cloned()
.map(|v| (v, Vec::new())), .map(|v| (v, Vec::new())),
mir::IndexedVariableReferenceKind::Index(inner, idx) => { mir::IndexedVariableReferenceKind::ArrayIndex(inner, idx) => {
let (inner_val, mut indices) = inner.get_stack_value(scope)?; let (inner_val, mut indices) = inner.get_stack_value(scope)?;
match &inner_val.1 { match &inner_val.1 {
@ -184,6 +184,9 @@ impl IndexedVariableReference {
_ => panic!("Tried to codegen indexing a non-indexable value!"), _ => panic!("Tried to codegen indexing a non-indexable value!"),
} }
} }
mir::IndexedVariableReferenceKind::StructIndex(indexed_variable_reference, _) => {
todo!("codegen for indexed var refrence")
}
} }
} }
} }
@ -385,7 +388,7 @@ impl mir::Expression {
None None
} }
} }
mir::ExprKind::Index(expression, val_t, idx) => { mir::ExprKind::ArrayIndex(expression, val_t, idx) => {
let array = expression.codegen(scope)?; let array = expression.codegen(scope)?;
let ptr = scope let ptr = scope
.block .block
@ -428,6 +431,10 @@ impl mir::Expression {
Some(array) Some(array)
} }
mir::ExprKind::StructIndex(expression, type_kind, _) => {
todo!("codegen for struct index")
}
mir::ExprKind::Struct(_, items) => todo!("codegen for struct expression"),
} }
} }
} }
@ -511,6 +518,7 @@ impl TypeKind {
TypeKind::Array(elem_t, _) => Type::Ptr(Box::new(elem_t.get_type())), TypeKind::Array(elem_t, _) => Type::Ptr(Box::new(elem_t.get_type())),
TypeKind::Void => Type::Void, TypeKind::Void => Type::Void,
TypeKind::Vague(_) => panic!("Tried to compile a vague type!"), TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
TypeKind::CustomType(_, custom_type_kind) => todo!("codegen for custom type"),
} }
} }
} }

View File

@ -36,6 +36,8 @@ pub enum Token {
False, False,
/// `extern` /// `extern`
Extern, Extern,
/// `struct`
Struct,
// Symbols // Symbols
/// `;` /// `;`
@ -74,6 +76,8 @@ pub enum Token {
BracketClose, BracketClose,
/// `,` /// `,`
Comma, Comma,
/// `.`
Dot,
Eof, Eof,
} }
@ -211,6 +215,7 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
"false" => Token::False, "false" => Token::False,
"extern" => Token::Extern, "extern" => Token::Extern,
"pub" => Token::PubKeyword, "pub" => Token::PubKeyword,
"struct" => Token::Struct,
_ => Token::Identifier(value), _ => Token::Identifier(value),
}; };
variant variant
@ -249,6 +254,7 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
'{' => Token::BraceOpen, '{' => Token::BraceOpen,
'}' => Token::BraceClose, '}' => Token::BraceClose,
',' => Token::Comma, ',' => Token::Comma,
'.' => Token::Dot,
// Invalid token // Invalid token
_ => Err(Error::InvalidToken(*character, cursor.position))?, _ => Err(Error::InvalidToken(*character, cursor.position))?,
}; };

View File

@ -23,6 +23,9 @@ impl Display for Module {
for import in &self.imports { for import in &self.imports {
writeln!(inner_f, "{}", import)?; writeln!(inner_f, "{}", import)?;
} }
for typedef in &self.typedefs {
writeln!(inner_f, "{}", typedef)?;
}
for fun in &self.functions { for fun in &self.functions {
writeln!(inner_f, "{}", fun)?; writeln!(inner_f, "{}", fun)?;
} }
@ -36,6 +39,31 @@ impl Display for Import {
} }
} }
impl Display for TypeDefinition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "type {} = ", self.name)?;
Display::fmt(&self.kind, f)
}
}
impl Display for TypeDefinitionKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TypeDefinitionKind::Struct(items) => {
write!(f, "struct ")?;
f.write_char('{')?;
writeln!(f)?;
let mut state = Default::default();
let mut inner_f = PadAdapter::wrap(f, &mut state);
for (field_name, field_ty) in items {
writeln!(inner_f, "{}: {:?},", field_name, field_ty)?;
}
f.write_char('}')
}
}
}
}
impl Display for FunctionDefinition { impl Display for FunctionDefinition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!( write!(
@ -130,7 +158,7 @@ impl Display for ExprKind {
ExprKind::FunctionCall(fc) => Display::fmt(fc, f), ExprKind::FunctionCall(fc) => Display::fmt(fc, f),
ExprKind::If(if_exp) => Display::fmt(&if_exp, f), ExprKind::If(if_exp) => Display::fmt(&if_exp, f),
ExprKind::Block(block) => Display::fmt(block, f), ExprKind::Block(block) => Display::fmt(block, f),
ExprKind::Index(expression, elem_ty, idx) => { ExprKind::ArrayIndex(expression, elem_ty, idx) => {
Display::fmt(&expression, f)?; Display::fmt(&expression, f)?;
write!(f, "<{}>", elem_ty)?; write!(f, "<{}>", elem_ty)?;
write_index(f, *idx) write_index(f, *idx)
@ -152,6 +180,28 @@ impl Display for ExprKind {
} }
f.write_char(']') f.write_char(']')
} }
ExprKind::Struct(name, items) => {
write!(f, "{} ", name)?;
f.write_char('{')?;
let mut state = Default::default();
let mut inner_f = PadAdapter::wrap(f, &mut state);
let mut iter = items.iter();
if let Some((name, expr)) = iter.next() {
write!(inner_f, "\n{}: {}", name, expr)?;
while let Some((name, expr)) = iter.next() {
writeln!(inner_f, ",")?;
write!(inner_f, "{}: {}", name, expr)?;
}
writeln!(inner_f, "")?;
}
f.write_char('}')
}
ExprKind::StructIndex(expression, type_kind, name) => {
Display::fmt(&expression, f)?;
write!(f, "<{}>", type_kind)?;
write_access(f, name)
}
} }
} }
} }
@ -190,10 +240,14 @@ impl Display for IndexedVariableReference {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.kind { match &self.kind {
IndexedVariableReferenceKind::Named(name) => Display::fmt(name, f), IndexedVariableReferenceKind::Named(name) => Display::fmt(name, f),
IndexedVariableReferenceKind::Index(variable_reference_kind, idx) => { IndexedVariableReferenceKind::ArrayIndex(var_ref, idx) => {
Display::fmt(&variable_reference_kind, f)?; Display::fmt(&var_ref, f)?;
write_index(f, *idx) write_index(f, *idx)
} }
IndexedVariableReferenceKind::StructIndex(var_ref, name) => {
Display::fmt(&var_ref, f)?;
write_access(f, name)
}
} }
} }
} }
@ -254,3 +308,8 @@ fn write_index(f: &mut std::fmt::Formatter<'_>, idx: u64) -> std::fmt::Result {
Display::fmt(&idx, f)?; Display::fmt(&idx, f)?;
f.write_char(']') f.write_char(']')
} }
fn write_access(f: &mut std::fmt::Formatter<'_>, name: &String) -> std::fmt::Result {
f.write_char('.')?;
Display::fmt(name, f)
}

View File

@ -4,7 +4,7 @@
use std::path::PathBuf; use std::path::PathBuf;
use crate::token_stream::TokenRange; use crate::{ast::Type, token_stream::TokenRange};
mod display; mod display;
pub mod linker; pub mod linker;
@ -65,6 +65,8 @@ pub enum TypeKind {
StringPtr, StringPtr,
#[error("[{0}; {1}]")] #[error("[{0}; {1}]")]
Array(Box<TypeKind>, u64), Array(Box<TypeKind>, u64),
#[error("{0} ({1})")]
CustomType(String, CustomTypeKind),
#[error(transparent)] #[error(transparent)]
Vague(#[from] VagueType), Vague(#[from] VagueType),
} }
@ -79,6 +81,14 @@ pub enum VagueType {
TypeRef(usize), TypeRef(usize),
} }
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum CustomTypeKind {
#[error("struct({0:?})")]
Struct(Vec<TypeKind>),
#[error("CustomType")]
Unknown,
}
impl TypeKind { impl TypeKind {
pub fn known(&self) -> Result<TypeKind, VagueType> { pub fn known(&self) -> Result<TypeKind, VagueType> {
if let TypeKind::Vague(vague) = self { if let TypeKind::Vague(vague) = self {
@ -107,6 +117,7 @@ impl TypeKind {
TypeKind::U128 => false, TypeKind::U128 => false,
TypeKind::StringPtr => false, TypeKind::StringPtr => false,
TypeKind::Array(_, _) => false, TypeKind::Array(_, _) => false,
TypeKind::CustomType(_, _) => false,
} }
} }
@ -126,8 +137,9 @@ impl TypeKind {
Bool => true, Bool => true,
Vague(_) => false, Vague(_) => false,
Void => false, Void => false,
TypeKind::StringPtr => false, StringPtr => false,
Array(_, _) => false, Array(_, _) => false,
TypeKind::CustomType(_, _) => false,
} }
} }
} }
@ -217,8 +229,10 @@ pub struct Import(pub Vec<String>, pub Metadata);
#[derive(Debug)] #[derive(Debug)]
pub enum ExprKind { pub enum ExprKind {
Variable(NamedVariableRef), Variable(NamedVariableRef),
Index(Box<Expression>, TypeKind, u64), ArrayIndex(Box<Expression>, TypeKind, u64),
StructIndex(Box<Expression>, TypeKind, String),
Array(Vec<Expression>), Array(Vec<Expression>),
Struct(String, Vec<(String, Expression)>),
Literal(Literal), Literal(Literal),
BinOp(BinaryOperator, Box<Expression>, Box<Expression>), BinOp(BinaryOperator, Box<Expression>, Box<Expression>),
FunctionCall(FunctionCall), FunctionCall(FunctionCall),
@ -294,7 +308,8 @@ pub struct IndexedVariableReference {
#[derive(Debug)] #[derive(Debug)]
pub enum IndexedVariableReferenceKind { pub enum IndexedVariableReferenceKind {
Named(NamedVariableRef), Named(NamedVariableRef),
Index(Box<IndexedVariableReference>, u64), ArrayIndex(Box<IndexedVariableReference>, u64),
StructIndex(Box<IndexedVariableReference>, String),
} }
#[derive(Debug)] #[derive(Debug)]
@ -306,11 +321,24 @@ pub enum StmtKind {
Expression(Expression), Expression(Expression),
} }
#[derive(Debug)]
pub struct TypeDefinition {
pub name: String,
pub kind: TypeDefinitionKind,
pub meta: Metadata,
}
#[derive(Debug)]
pub enum TypeDefinitionKind {
Struct(Vec<(String, Type)>),
}
#[derive(Debug)] #[derive(Debug)]
pub struct Module { pub struct Module {
pub name: String, pub name: String,
pub imports: Vec<Import>, pub imports: Vec<Import>,
pub functions: Vec<FunctionDefinition>, pub functions: Vec<FunctionDefinition>,
pub typedefs: Vec<TypeDefinition>,
pub path: Option<PathBuf>, pub path: Option<PathBuf>,
pub is_main: bool, pub is_main: bool,
} }

View File

@ -427,7 +427,7 @@ impl Expression {
Ok((_, ty)) => Ok(ty), Ok((_, ty)) => Ok(ty),
Err(e) => Err(e), Err(e) => Err(e),
}, },
ExprKind::Index(expression, elem_ty, idx) => { ExprKind::ArrayIndex(expression, elem_ty, idx) => {
// Try to unwrap hint type from array if possible // Try to unwrap hint type from array if possible
let hint_t = hint_t.map(|t| match t { let hint_t = hint_t.map(|t| match t {
TypeKind::Array(type_kind, _) => &type_kind, TypeKind::Array(type_kind, _) => &type_kind,
@ -487,6 +487,10 @@ impl Expression {
} }
} }
} }
ExprKind::StructIndex(expression, type_kind, _) => {
todo!("typechecking for struct index")
}
ExprKind::Struct(_, items) => todo!("typechecking for struct expression"),
} }
} }
} }
@ -500,7 +504,7 @@ impl IndexedVariableReference {
IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => { IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => {
Ok(storage.get(&name).cloned()) Ok(storage.get(&name).cloned())
} }
IndexedVariableReferenceKind::Index(inner_ref, _) => { IndexedVariableReferenceKind::ArrayIndex(inner_ref, _) => {
if let Some(var) = inner_ref.get_variable(storage)? { if let Some(var) = inner_ref.get_variable(storage)? {
match &var.ty { match &var.ty {
TypeKind::Array(inner_ty, _) => Ok(Some(ScopeVariable { TypeKind::Array(inner_ty, _) => Ok(Some(ScopeVariable {
@ -513,6 +517,9 @@ impl IndexedVariableReference {
Ok(None) Ok(None)
} }
} }
IndexedVariableReferenceKind::StructIndex(indexed_variable_reference, _) => {
todo!("struct index refrence typecheck")
}
} }
} }
} }

View File

@ -161,7 +161,7 @@ impl IndexedVariableReference {
super::IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => { super::IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => {
Ok(hints.find_hint(&name)) Ok(hints.find_hint(&name))
} }
super::IndexedVariableReferenceKind::Index(inner, _) => { super::IndexedVariableReferenceKind::ArrayIndex(inner, _) => {
if let Some((mutable, inner_ref)) = inner.find_hint(hints)? { if let Some((mutable, inner_ref)) = inner.find_hint(hints)? {
// Check that the resolved type is at least an array, no // Check that the resolved type is at least an array, no
// need for further resolution. // need for further resolution.
@ -177,6 +177,9 @@ impl IndexedVariableReference {
Ok(None) Ok(None)
} }
} }
super::IndexedVariableReferenceKind::StructIndex(indexed_variable_reference, _) => {
todo!("struct index refrence type inference")
}
} }
} }
} }
@ -283,7 +286,7 @@ impl Expression {
ReturnKind::Soft => Ok(block_ref.1), ReturnKind::Soft => Ok(block_ref.1),
} }
} }
ExprKind::Index(expression, index_ty, _) => { ExprKind::ArrayIndex(expression, index_ty, _) => {
let expr_ty = expression.infer_types(state, type_refs)?; let expr_ty = expression.infer_types(state, type_refs)?;
// Check that the resolved type is at least an array, no // Check that the resolved type is at least an array, no
@ -336,6 +339,10 @@ impl Expression {
} }
} }
} }
ExprKind::StructIndex(expression, type_kind, _) => {
todo!("type inference for struct indexes")
}
ExprKind::Struct(_, items) => todo!("type inference for struct expression"),
} }
} }
} }

View File

@ -1,3 +1,5 @@
use crate::util::try_all;
use super::*; use super::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -87,7 +89,7 @@ impl ReturnType for Expression {
Block(block) => block.return_type(), Block(block) => block.return_type(),
FunctionCall(fcall) => fcall.return_type(), FunctionCall(fcall) => fcall.return_type(),
If(expr) => expr.return_type(), If(expr) => expr.return_type(),
Index(expression, _, _) => { ArrayIndex(expression, _, _) => {
let expr_type = expression.return_type()?; let expr_type = expression.return_type()?;
if let (_, TypeKind::Array(elem_ty, _)) = expr_type { if let (_, TypeKind::Array(elem_ty, _)) = expr_type {
Ok((ReturnKind::Soft, *elem_ty)) Ok((ReturnKind::Soft, *elem_ty))
@ -106,6 +108,18 @@ impl ReturnType for Expression {
TypeKind::Array(Box::new(first.1), expressions.len() as u64), TypeKind::Array(Box::new(first.1), expressions.len() as u64),
)) ))
} }
StructIndex(expression, type_kind, _) => todo!("todo return type for struct index"),
Struct(name, items) => {
let f_types = try_all(items.iter().map(|e| e.1.return_type()).collect())
.map_err(|e| unsafe { e.get_unchecked(0).clone() })?
.iter()
.map(|r| r.1.clone())
.collect();
Ok((
ReturnKind::Soft,
TypeKind::CustomType(name.clone(), CustomTypeKind::Struct(f_types)),
))
}
} }
} }
} }
@ -165,9 +179,12 @@ impl IndexedVariableReference {
pub fn get_name(&self) -> String { pub fn get_name(&self) -> String {
match &self.kind { match &self.kind {
IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => name.clone(), IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => name.clone(),
IndexedVariableReferenceKind::Index(inner, idx) => { IndexedVariableReferenceKind::ArrayIndex(inner, idx) => {
format!("{}[{}]", inner.get_name(), idx) format!("{}[{}]", inner.get_name(), idx)
} }
IndexedVariableReferenceKind::StructIndex(inner, name) => {
format!("{}.{}", inner.get_name(), name)
}
} }
} }
@ -176,7 +193,8 @@ impl IndexedVariableReference {
IndexedVariableReferenceKind::Named(NamedVariableRef(ty, _, _)) => { IndexedVariableReferenceKind::Named(NamedVariableRef(ty, _, _)) => {
*ty = new_ty.clone(); *ty = new_ty.clone();
} }
IndexedVariableReferenceKind::Index(inner, _) => inner.update_type(new_ty), IndexedVariableReferenceKind::ArrayIndex(inner, _) => inner.update_type(new_ty),
IndexedVariableReferenceKind::StructIndex(inner, _) => inner.update_type(new_ty),
} }
} }
} }

View File

@ -63,6 +63,14 @@ impl<'a, 'b> TokenStream<'a, 'b> {
} }
} }
pub fn peek2(&mut self) -> Option<Token> {
if self.tokens.len() < (self.position + 1) {
None
} else {
Some(self.tokens[self.position + 1].token.clone())
}
}
/// Parse the next value of trait Parse. If the parse succeeded, the related /// Parse the next value of trait Parse. If the parse succeeded, the related
/// tokens are consumed, otherwise token stream does not advance. /// tokens are consumed, otherwise token stream does not advance.
/// ///

15
reid_src/struct.reid Normal file
View File

@ -0,0 +1,15 @@
// Arithmetic, function calls and imports!
struct Test {
field: i32,
second: u32
}
fn main() -> u32 {
let value = Test {
field: 5,
second: 3,
};
return Test.second;
}