Skip to content

Commit

Permalink
Temp 8
Browse files Browse the repository at this point in the history
  • Loading branch information
Rigidity committed Jul 23, 2024
1 parent 8bd10ae commit 564e397
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 101 deletions.
49 changes: 31 additions & 18 deletions crates/rue-compiler/src/compiler/expr/field_access_expr.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use rue_parser::FieldAccessExpr;
use rue_typing::{deconstruct_items, Rest, Type};

use crate::{
compiler::Compiler,
hir::{Hir, Op},
value::{GuardPathItem, PairType, Rest, Type, Value},
value::{GuardPathItem, Value},
ErrorKind,
};

Expand All @@ -21,22 +22,24 @@ impl Compiler<'_> {
return self.unknown();
};

let mut new_value = match self.db.ty(old_value.type_id).clone() {
Type::Struct(struct_type) => {
if let Some((index, _, &field_type)) =
struct_type.fields.get_full(field_name.text())
{
let mut type_id = field_type;
let mut new_value = match self.ty.get(old_value.type_id).clone() {
Type::Struct(ty) => {
let fields = deconstruct_items(self.ty, ty.type_id, ty.field_names.len(), ty.rest)
.expect("invalid struct type");

if index == struct_type.fields.len() - 1 && struct_type.rest == Rest::Optional {
type_id = self.ty.alloc(Type::Optional(type_id));
if let Some(index) = ty.field_names.get_index_of(field_name.text()) {
let type_id = fields[index];

if index == ty.field_names.len() - 1 && ty.rest == Rest::Optional {
todo!();
// TODO: type_id = self.ty.alloc(Type::Optional(type_id));
}

Value::new(
self.compile_index(
old_value.hir_id,
index,
index == struct_type.fields.len() - 1 && struct_type.rest != Rest::Nil,
index == ty.field_names.len() - 1 && ty.rest != Rest::Nil,
),
type_id,
)
Expand All @@ -49,14 +52,24 @@ impl Compiler<'_> {
return self.unknown();
}
}
Type::EnumVariant(variant_type) => {
let fields = variant_type.fields.unwrap_or_default();
Type::Variant(variant) => {
let field_names = variant.field_names.clone().unwrap_or_default();

let fields = variant
.field_names
.as_ref()
.map(|field_names| {
deconstruct_items(self.ty, variant.type_id, field_names.len(), variant.rest)
.expect("invalid struct type")
})
.unwrap_or_default();

if let Some((index, _, &field_type)) = fields.get_full(field_name.text()) {
let mut type_id = field_type;
if let Some(index) = field_names.get_index_of(field_name.text()) {
let type_id = fields[index];

if index == fields.len() - 1 && variant_type.rest == Rest::Optional {
type_id = self.ty.alloc(Type::Optional(type_id));
if index == fields.len() - 1 && variant.rest == Rest::Optional {
// TODO: type_id = self.ty.alloc(Type::Optional(type_id));
todo!()
}

let fields_hir_id = self.db.alloc_hir(Hir::Op(Op::Rest, old_value.hir_id));
Expand All @@ -65,7 +78,7 @@ impl Compiler<'_> {
self.compile_index(
fields_hir_id,
index,
index == fields.len() - 1 && variant_type.rest != Rest::Nil,
index == fields.len() - 1 && variant.rest != Rest::Nil,
),
type_id,
)
Expand All @@ -78,7 +91,7 @@ impl Compiler<'_> {
return self.unknown();
}
}
Type::Pair(PairType { first, rest }) => match field_name.text() {
Type::Pair(first, rest) => match field_name.text() {
"first" => Value::new(
self.db.alloc_hir(Hir::Op(Op::First, old_value.hir_id)),
first,
Expand Down
3 changes: 2 additions & 1 deletion crates/rue-compiler/src/compiler/expr/group_expr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rue_parser::GroupExpr;
use rue_typing::TypeId;

use crate::{compiler::Compiler, value::Value, TypeId};
use crate::{compiler::Compiler, value::Value};

impl Compiler<'_> {
pub fn compile_group_expr(
Expand Down
8 changes: 2 additions & 6 deletions crates/rue-compiler/src/compiler/expr/list_expr.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
use rue_parser::{AstNode, ListExpr};
use rue_typing::{Type, TypeId};

use crate::{
compiler::Compiler,
hir::Hir,
value::{Type, Value},
ErrorKind, TypeId,
};
use crate::{compiler::Compiler, hir::Hir, value::Value, ErrorKind};

impl Compiler<'_> {
pub fn compile_list_expr(
Expand Down
21 changes: 3 additions & 18 deletions crates/rue-compiler/src/compiler/expr/literal_expr.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use clvmr::Allocator;
use num_bigint::BigInt;
use rue_parser::{LiteralExpr, SyntaxKind, SyntaxToken};
use rue_typing::bigint_to_bytes;

use crate::{compiler::Compiler, hir::Hir, value::Value, ErrorKind};
use crate::{compiler::Compiler, hir::Hir, value::Value};

impl Compiler<'_> {
pub fn compile_literal_expr(&mut self, literal: &LiteralExpr) -> Value {
Expand Down Expand Up @@ -39,10 +38,7 @@ impl Compiler<'_> {
.parse()
.expect("failed to parse integer literal");

let atom = Self::bigint_to_bytes(bigint).unwrap_or_else(|| {
self.db.error(ErrorKind::IntegerTooLarge, int.text_range());
Vec::new()
});
let atom = bigint_to_bytes(bigint);

// Extract the atom representation of the number.
Value::new(self.db.alloc_hir(Hir::Atom(atom)), self.ty.std().int)
Expand Down Expand Up @@ -92,15 +88,4 @@ impl Compiler<'_> {
self.ty.std().bytes,
)
}

pub fn bigint_to_bytes(bigint: BigInt) -> Option<Vec<u8>> {
// Create a CLVM allocator.
let mut allocator = Allocator::new();

// Try to allocate the number.
let ptr = allocator.new_number(bigint).ok()?;

// Extract the atom representation of the number.
Some(allocator.atom(ptr).as_ref().to_vec())
}
}
4 changes: 2 additions & 2 deletions crates/rue-compiler/src/compiler/expr/pair_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use crate::{compiler::Compiler, hir::Hir, value::Value};
impl Compiler<'_> {
pub fn compile_pair_expr(&mut self, pair: &PairExpr, expected_type: Option<TypeId>) -> Value {
// Extract the first and rest type out of the expected type.
let first = expected_type.and_then(|type_id| self.ty.pair_first(type_id));
let rest = expected_type.and_then(|type_id| self.ty.pair_rest(type_id));
let first = expected_type.and_then(|type_id| Some(self.ty.get_pair(type_id)?.0));
let rest = expected_type.and_then(|type_id| Some(self.ty.get_pair(type_id)?.1));

// Compile the first expression, if present.
// It's a parser error if not, so it's fine to return unknown.
Expand Down
66 changes: 36 additions & 30 deletions crates/rue-compiler/src/compiler/item/enum_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@ use indexmap::IndexMap;
use num_bigint::BigInt;
use num_traits::Zero;
use rue_parser::EnumItem;
use rue_typing::{construct_items, Enum, Type, TypeId, Variant};

use crate::{
compiler::Compiler,
hir::Hir,
value::{EnumType, EnumVariantType, Type},
ErrorKind, TypeId,
};
use crate::{compiler::Compiler, ErrorKind};

impl Compiler<'_> {
pub fn declare_enum_item(&mut self, enum_item: &EnumItem) -> TypeId {
Expand Down Expand Up @@ -41,30 +37,36 @@ impl Compiler<'_> {

// Allocate a new type for the variant.
// It has to be `Unknown` for now, since field types may not be declared yet.
let type_id = self.ty.alloc(Type::Unknown);
let variant_type_id = self.ty.alloc(Type::Unknown);

// Add the variant to the enum and define the token for the variant.
variants.insert(name.to_string(), type_id);
self.db.insert_type_token(type_id, name);
variants.insert(name.to_string(), variant_type_id);
self.db.insert_type_token(variant_type_id, name);
}

// Allocate a new type for the enum.
let type_id = self.ty.alloc(Type::Enum(EnumType {
let enum_structure = self
.ty
.alloc(Type::Union(variants.values().copied().collect()));

let enum_type_id = self.ty.alloc(Type::Enum(Enum {
original_type_id: None,
type_id: enum_structure,
has_fields,
variants,
}));

// Add the enum to the scope and define the token for the enum.
if let Some(name) = enum_item.name() {
self.scope_mut().define_type(name.to_string(), type_id);
self.db.insert_type_token(type_id, name);
self.scope_mut().define_type(name.to_string(), enum_type_id);
self.db.insert_type_token(enum_type_id, name);
}

type_id
enum_type_id
}

pub fn compile_enum_item(&mut self, enum_item: &EnumItem, enum_type_id: TypeId) {
let Type::Enum(enum_type) = self.db.ty(enum_type_id).clone() else {
let Type::Enum(enum_type) = self.ty.get(enum_type_id).clone() else {
unreachable!();
};

Expand Down Expand Up @@ -132,29 +134,33 @@ impl Compiler<'_> {
BigInt::zero()
};

let atom = Self::bigint_to_bytes(discriminant).unwrap_or_else(|| {
self.db.error(
ErrorKind::EnumDiscriminantTooLarge,
variant
.discriminant()
.map_or(name.text_range(), |token| token.text_range()),
);
Vec::new()
});

let discriminant = self.db.alloc_hir(Hir::Atom(atom));

// Update the variant to use the real `EnumVariant` type.
*self.db.ty_mut(variant_type_id) = Type::EnumVariant(EnumVariantType {
let discriminant_type = self.ty.alloc(Type::Value(discriminant.clone()));

let type_id = if enum_type.has_fields {
construct_items(
self.ty,
[discriminant_type]
.into_iter()
.chain(fields.values().copied()),
rest,
)
} else {
discriminant_type
};

*self.ty.get_mut(variant_type_id) = Type::Variant(Variant {
original_type_id: None,
enum_type: enum_type_id,
original_type_id: variant_type_id,
fields: if variant.fields().is_some() {
Some(fields)
field_names: if variant.fields().is_some() {
Some(fields.keys().cloned().collect())
} else {
None
},
type_id,
rest,
discriminant,
generic_types: Vec::new(),
});

self.type_definition_stack.pop().unwrap();
Expand Down
19 changes: 13 additions & 6 deletions crates/rue-compiler/src/compiler/item/function_item.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use rue_parser::{AstNode, FunctionItem};
use rue_typing::{construct_items, Callable, Rest, Type};

use crate::{
compiler::Compiler,
hir::Hir,
scope::Scope,
symbol::{Function, Symbol},
value::{FunctionType, Rest, Type},
ErrorKind, SymbolId,
};

Expand Down Expand Up @@ -49,6 +49,7 @@ impl Compiler<'_> {
}

let mut param_types = Vec::new();
let mut param_names = Vec::new();
let mut rest = Rest::Nil;

let params = function_item.params();
Expand All @@ -73,7 +74,8 @@ impl Compiler<'_> {
*self.db.symbol_mut(symbol_id) = Symbol::Parameter(if param.optional().is_some() {
// If the parameter is optional, wrap the type in a possibly undefined type.
// This prevents referencing the parameter until it's checked for undefined.
self.ty.alloc(Type::Optional(type_id))
// TODO: self.ty.alloc(Type::Optional(type_id))
todo!()
} else {
// Otherwise, just use the type.
type_id
Expand All @@ -88,8 +90,11 @@ impl Compiler<'_> {
);
}

param_names.push(name.to_string());
self.scope_mut().define_symbol(name.to_string(), symbol_id);
self.db.insert_symbol_token(symbol_id, name);
} else {
param_names.push(format!("#{}", i));
}

// Check if it's a spread or optional parameter.
Expand Down Expand Up @@ -133,11 +138,13 @@ impl Compiler<'_> {
let hir_id = self.db.alloc_hir(Hir::Unknown);

// Create the function's type.
let ty = FunctionType {
generic_types,
param_types,
rest,
let ty = Callable {
original_type_id: None,
parameter_names: param_names.into_iter().collect(),
parameters: construct_items(self.ty, param_types.into_iter(), rest),
return_type,
rest,
generic_types,
};

// Update the symbol with the function.
Expand Down
23 changes: 13 additions & 10 deletions crates/rue-compiler/src/compiler/item/struct_item.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use indexmap::IndexMap;
use rue_parser::{AstNode, StructField, StructItem};
use rue_typing::{construct_items, Rest, Struct, Type, TypeId};

use crate::{
compiler::Compiler,
value::{Rest, StructType, Type},
ErrorKind, TypeId,
};
use crate::{compiler::Compiler, ErrorKind};

impl Compiler<'_> {
/// Define a type for a struct in the current scope, but leave it as unknown for now.
Expand All @@ -19,14 +16,20 @@ impl Compiler<'_> {
}

/// Compile and resolve a struct type.
pub fn compile_struct_item(&mut self, struct_item: &StructItem, type_id: TypeId) {
self.type_definition_stack.push(type_id);
pub fn compile_struct_item(&mut self, struct_item: &StructItem, struct_type_id: TypeId) {
self.type_definition_stack.push(struct_type_id);

let (fields, rest) = self.compile_struct_fields(struct_item.fields());
*self.db.ty_mut(type_id) = Type::Struct(StructType {
original_type_id: type_id,
fields,
let type_id = construct_items(self.ty, fields.values().copied(), rest);

*self.ty.get_mut(struct_type_id) = Type::Struct(Struct {
original_type_id: None,
field_names: fields.keys().cloned().collect(),
type_id,
rest,
generic_types: Vec::new(),
});

self.type_definition_stack.pop().unwrap();
}

Expand Down
3 changes: 2 additions & 1 deletion crates/rue-compiler/src/compiler/stmt/if_stmt.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::collections::HashMap;

use rue_parser::{AstNode, IfStmt};
use rue_typing::TypeId;

use crate::{
compiler::{block::BlockTerminator, Compiler},
scope::Scope,
value::{GuardPath, TypeOverride},
ErrorKind, HirId, TypeId,
ErrorKind, HirId,
};

impl Compiler<'_> {
Expand Down
Loading

0 comments on commit 564e397

Please sign in to comment.