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)
- ~~Strings~~ (DONE)
- Loops
- Debug Information
### Why "Reid"

View File

@ -14,7 +14,7 @@
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: ""$?"

View File

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

View File

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

View File

@ -263,3 +263,14 @@ pub enum TerminatorKind {
Br(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_lib::compile::CompileOutput;

View File

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

View File

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

View File

@ -76,10 +76,24 @@ impl Parse for PrimaryExpression {
)
} else if let Ok(ifexpr) = stream.parse() {
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() {
match &token {
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(
Kind::Literal(Literal::Number(*v)),
@ -120,11 +134,21 @@ impl Parse for PrimaryExpression {
Err(stream.expected_err("expression")?)?
};
while let Ok(ValueIndex(idx)) = stream.parse() {
expr = Expression(
ExpressionKind::Index(Box::new(expr), idx),
stream.get_range().unwrap(),
);
while let Ok(index) = stream.parse::<ValueIndex>() {
match index {
ValueIndex::Array(ArrayValueIndex(idx)) => {
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))
@ -401,9 +425,9 @@ impl Parse for VariableReference {
stream.get_range().unwrap(),
);
while let Ok(ValueIndex(idx)) = stream.parse() {
while let Ok(ArrayValueIndex(idx)) = stream.parse() {
var_ref = VariableReference(
VariableReferenceKind::Index(Box::new(var_ref), idx),
VariableReferenceKind::ArrayIndex(Box::new(var_ref), idx),
stream.get_range().unwrap(),
);
}
@ -415,21 +439,101 @@ impl Parse for VariableReference {
}
}
#[derive(Debug, Clone, Copy)]
pub struct ValueIndex(u64);
impl Parse for StructExpression {
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 {
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> {
stream.expect(Token::BracketOpen)?;
if let Some(Token::DecimalValue(idx)) = stream.next() {
stream.expect(Token::BracketClose)?;
Ok(ValueIndex(idx))
Ok(ArrayValueIndex(idx))
} else {
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 {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
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 {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
use TopLevelStatement as Stmt;
@ -491,6 +622,14 @@ impl Parse for TopLevelStatement {
Some(Token::FnKeyword) | Some(Token::PubKeyword) => {
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")?)?,
})
}

View File

@ -15,6 +15,7 @@ impl ast::Module {
pub fn process(&self) -> mir::Module {
let mut imports = Vec::new();
let mut functions = Vec::new();
let mut typedefs = Vec::new();
use ast::TopLevelStatement::*;
for stmt in &self.top_level_statements {
@ -62,6 +63,23 @@ impl ast::Module {
};
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,
path: self.path.clone(),
is_main: self.is_main,
typedefs,
}
}
}
@ -151,8 +170,14 @@ impl ast::VariableReferenceKind {
(*range).into(),
))
}
ast::VariableReferenceKind::Index(var_ref, idx) => {
mir::IndexedVariableReferenceKind::Index(Box::new(var_ref.process()), *idx)
ast::VariableReferenceKind::ArrayIndex(var_ref, 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) => {
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()),
mir::TypeKind::Vague(mir::VagueType::Unknown),
*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())
@ -249,6 +287,7 @@ impl From<ast::TypeKind> for mir::TypeKind {
mir::TypeKind::Array(Box::new(mir::TypeKind::from(*type_kind.clone())), *length)
}
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)
.cloned()
.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)?;
match &inner_val.1 {
@ -184,6 +184,9 @@ impl IndexedVariableReference {
_ => 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
}
}
mir::ExprKind::Index(expression, val_t, idx) => {
mir::ExprKind::ArrayIndex(expression, val_t, idx) => {
let array = expression.codegen(scope)?;
let ptr = scope
.block
@ -428,6 +431,10 @@ impl mir::Expression {
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::Void => Type::Void,
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,
/// `extern`
Extern,
/// `struct`
Struct,
// Symbols
/// `;`
@ -74,6 +76,8 @@ pub enum Token {
BracketClose,
/// `,`
Comma,
/// `.`
Dot,
Eof,
}
@ -211,6 +215,7 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
"false" => Token::False,
"extern" => Token::Extern,
"pub" => Token::PubKeyword,
"struct" => Token::Struct,
_ => Token::Identifier(value),
};
variant
@ -249,6 +254,7 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
'{' => Token::BraceOpen,
'}' => Token::BraceClose,
',' => Token::Comma,
'.' => Token::Dot,
// Invalid token
_ => Err(Error::InvalidToken(*character, cursor.position))?,
};

View File

@ -23,6 +23,9 @@ impl Display for Module {
for import in &self.imports {
writeln!(inner_f, "{}", import)?;
}
for typedef in &self.typedefs {
writeln!(inner_f, "{}", typedef)?;
}
for fun in &self.functions {
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 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
@ -130,7 +158,7 @@ impl Display for ExprKind {
ExprKind::FunctionCall(fc) => Display::fmt(fc, f),
ExprKind::If(if_exp) => Display::fmt(&if_exp, f),
ExprKind::Block(block) => Display::fmt(block, f),
ExprKind::Index(expression, elem_ty, idx) => {
ExprKind::ArrayIndex(expression, elem_ty, idx) => {
Display::fmt(&expression, f)?;
write!(f, "<{}>", elem_ty)?;
write_index(f, *idx)
@ -152,6 +180,28 @@ impl Display for ExprKind {
}
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 {
match &self.kind {
IndexedVariableReferenceKind::Named(name) => Display::fmt(name, f),
IndexedVariableReferenceKind::Index(variable_reference_kind, idx) => {
Display::fmt(&variable_reference_kind, f)?;
IndexedVariableReferenceKind::ArrayIndex(var_ref, idx) => {
Display::fmt(&var_ref, f)?;
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)?;
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 crate::token_stream::TokenRange;
use crate::{ast::Type, token_stream::TokenRange};
mod display;
pub mod linker;
@ -65,6 +65,8 @@ pub enum TypeKind {
StringPtr,
#[error("[{0}; {1}]")]
Array(Box<TypeKind>, u64),
#[error("{0} ({1})")]
CustomType(String, CustomTypeKind),
#[error(transparent)]
Vague(#[from] VagueType),
}
@ -79,6 +81,14 @@ pub enum VagueType {
TypeRef(usize),
}
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum CustomTypeKind {
#[error("struct({0:?})")]
Struct(Vec<TypeKind>),
#[error("CustomType")]
Unknown,
}
impl TypeKind {
pub fn known(&self) -> Result<TypeKind, VagueType> {
if let TypeKind::Vague(vague) = self {
@ -107,6 +117,7 @@ impl TypeKind {
TypeKind::U128 => false,
TypeKind::StringPtr => false,
TypeKind::Array(_, _) => false,
TypeKind::CustomType(_, _) => false,
}
}
@ -126,8 +137,9 @@ impl TypeKind {
Bool => true,
Vague(_) => false,
Void => false,
TypeKind::StringPtr => false,
StringPtr => false,
Array(_, _) => false,
TypeKind::CustomType(_, _) => false,
}
}
}
@ -217,8 +229,10 @@ pub struct Import(pub Vec<String>, pub Metadata);
#[derive(Debug)]
pub enum ExprKind {
Variable(NamedVariableRef),
Index(Box<Expression>, TypeKind, u64),
ArrayIndex(Box<Expression>, TypeKind, u64),
StructIndex(Box<Expression>, TypeKind, String),
Array(Vec<Expression>),
Struct(String, Vec<(String, Expression)>),
Literal(Literal),
BinOp(BinaryOperator, Box<Expression>, Box<Expression>),
FunctionCall(FunctionCall),
@ -294,7 +308,8 @@ pub struct IndexedVariableReference {
#[derive(Debug)]
pub enum IndexedVariableReferenceKind {
Named(NamedVariableRef),
Index(Box<IndexedVariableReference>, u64),
ArrayIndex(Box<IndexedVariableReference>, u64),
StructIndex(Box<IndexedVariableReference>, String),
}
#[derive(Debug)]
@ -306,11 +321,24 @@ pub enum StmtKind {
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)]
pub struct Module {
pub name: String,
pub imports: Vec<Import>,
pub functions: Vec<FunctionDefinition>,
pub typedefs: Vec<TypeDefinition>,
pub path: Option<PathBuf>,
pub is_main: bool,
}

View File

@ -427,7 +427,7 @@ impl Expression {
Ok((_, ty)) => Ok(ty),
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
let hint_t = hint_t.map(|t| match t {
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, _)) => {
Ok(storage.get(&name).cloned())
}
IndexedVariableReferenceKind::Index(inner_ref, _) => {
IndexedVariableReferenceKind::ArrayIndex(inner_ref, _) => {
if let Some(var) = inner_ref.get_variable(storage)? {
match &var.ty {
TypeKind::Array(inner_ty, _) => Ok(Some(ScopeVariable {
@ -513,6 +517,9 @@ impl IndexedVariableReference {
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, _)) => {
Ok(hints.find_hint(&name))
}
super::IndexedVariableReferenceKind::Index(inner, _) => {
super::IndexedVariableReferenceKind::ArrayIndex(inner, _) => {
if let Some((mutable, inner_ref)) = inner.find_hint(hints)? {
// Check that the resolved type is at least an array, no
// need for further resolution.
@ -177,6 +177,9 @@ impl IndexedVariableReference {
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),
}
}
ExprKind::Index(expression, index_ty, _) => {
ExprKind::ArrayIndex(expression, index_ty, _) => {
let expr_ty = expression.infer_types(state, type_refs)?;
// 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::*;
#[derive(Debug, Clone)]
@ -87,7 +89,7 @@ impl ReturnType for Expression {
Block(block) => block.return_type(),
FunctionCall(fcall) => fcall.return_type(),
If(expr) => expr.return_type(),
Index(expression, _, _) => {
ArrayIndex(expression, _, _) => {
let expr_type = expression.return_type()?;
if let (_, TypeKind::Array(elem_ty, _)) = expr_type {
Ok((ReturnKind::Soft, *elem_ty))
@ -106,6 +108,18 @@ impl ReturnType for Expression {
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 {
match &self.kind {
IndexedVariableReferenceKind::Named(NamedVariableRef(_, name, _)) => name.clone(),
IndexedVariableReferenceKind::Index(inner, idx) => {
IndexedVariableReferenceKind::ArrayIndex(inner, 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, _, _)) => {
*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
/// 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;
}