Merge branch 'main' into intrinsicts
This commit is contained in:
commit
4f1dc5e59d
@ -47,7 +47,7 @@ Currently missing big features (TODOs) are:
|
|||||||
- Debug Information (PARTIALLY DONE)
|
- Debug Information (PARTIALLY DONE)
|
||||||
- Ability to specify types in literals and variable definitions
|
- Ability to specify types in literals and variable definitions
|
||||||
- Intrinsic functions
|
- Intrinsic functions
|
||||||
- Not-Unary
|
- Not-Unary and NEQ-binary
|
||||||
|
|
||||||
Big features that I want later but are not necessary:
|
Big features that I want later but are not necessary:
|
||||||
- Associated functions
|
- Associated functions
|
||||||
|
11
examples/for_loops.reid
Normal file
11
examples/for_loops.reid
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import std::print;
|
||||||
|
import std::from_str;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
for i in 0..1 {
|
||||||
|
print(from_str("Hello!"));
|
||||||
|
}
|
||||||
|
for i in 0..1 {
|
||||||
|
print(from_str("Hello!"));
|
||||||
|
}
|
||||||
|
}
|
27
examples/loop_hard.reid
Normal file
27
examples/loop_hard.reid
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import std::print;
|
||||||
|
import std::new_string;
|
||||||
|
import std::add_num_to_str;
|
||||||
|
import std::add_char;
|
||||||
|
|
||||||
|
fn main() -> u8 {
|
||||||
|
for i in 0..5 {
|
||||||
|
for j in 0..5 {
|
||||||
|
for k in 0..5 {
|
||||||
|
let mut test = new_string();
|
||||||
|
add_num_to_str(&mut test, i);
|
||||||
|
add_char(&mut test, ',');
|
||||||
|
add_num_to_str(&mut test, j);
|
||||||
|
add_char(&mut test, ',');
|
||||||
|
add_num_to_str(&mut test, k);
|
||||||
|
print(test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i in 0..1000 {
|
||||||
|
for j in 0..1000 {
|
||||||
|
for k in 0..1000 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
9
examples/ptr_hard.reid
Normal file
9
examples/ptr_hard.reid
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fn main() -> u8 {
|
||||||
|
let mut a = 5;
|
||||||
|
inner(&mut a);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(a: &mut i32) {
|
||||||
|
*a = *a + 1;
|
||||||
|
}
|
@ -676,7 +676,7 @@ impl FunctionHolder {
|
|||||||
|
|
||||||
let block_ref = LLVMCreateBasicBlockInContext(
|
let block_ref = LLVMCreateBasicBlockInContext(
|
||||||
module.context_ref,
|
module.context_ref,
|
||||||
into_cstring(&self.data.name).as_ptr(),
|
into_cstring(&block.data.name).as_ptr(),
|
||||||
);
|
);
|
||||||
LLVMAppendExistingBasicBlock(own_function.value_ref, block_ref);
|
LLVMAppendExistingBasicBlock(own_function.value_ref, block_ref);
|
||||||
module.blocks.insert(block.value, block_ref);
|
module.blocks.insert(block.value, block_ref);
|
||||||
|
183
reid/src/allocator.rs
Normal file
183
reid/src/allocator.rs
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use reid_lib::{
|
||||||
|
builder::{InstructionValue, TypeValue},
|
||||||
|
Block,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::mir::{
|
||||||
|
self, CustomTypeKey, FunctionCall, FunctionDefinition, IfExpression, SourceModuleId,
|
||||||
|
TypeDefinition, TypeKind, WhileStatement,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Allocator {
|
||||||
|
allocations: Vec<Allocation>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AllocatorScope<'ctx, 'a> {
|
||||||
|
pub(super) block: &'a mut Block<'ctx>,
|
||||||
|
pub(super) module_id: SourceModuleId,
|
||||||
|
pub(super) types: &'a HashMap<TypeValue, TypeDefinition>,
|
||||||
|
pub(super) type_values: &'a HashMap<CustomTypeKey, TypeValue>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Allocator {
|
||||||
|
pub fn from(func: &FunctionDefinition, scope: &mut AllocatorScope) -> Allocator {
|
||||||
|
func.allocate(scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn allocate(&mut self, name: &String, ty: &TypeKind) -> Option<InstructionValue> {
|
||||||
|
let mut allocs = self.allocations.iter().cloned().enumerate();
|
||||||
|
let val = allocs.find(|a| a.1 .0 == *name && a.1 .1 == *ty);
|
||||||
|
if let Some((i, _)) = val {
|
||||||
|
self.allocations.remove(i);
|
||||||
|
}
|
||||||
|
val.map(|v| v.1 .2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Allocation(String, TypeKind, InstructionValue);
|
||||||
|
|
||||||
|
impl mir::FunctionDefinition {
|
||||||
|
fn allocate<'ctx, 'a>(&self, scope: &mut AllocatorScope<'ctx, 'a>) -> Allocator {
|
||||||
|
let mut allocated = Vec::new();
|
||||||
|
match &self.kind {
|
||||||
|
crate::mir::FunctionDefinitionKind::Local(block, _) => {
|
||||||
|
for param in &self.parameters {
|
||||||
|
let allocation = scope
|
||||||
|
.block
|
||||||
|
.build_named(
|
||||||
|
param.0.clone(),
|
||||||
|
reid_lib::Instr::Alloca(
|
||||||
|
param.1.get_type(scope.type_values, scope.types),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
allocated.push(Allocation(param.0.clone(), param.1.clone(), allocation));
|
||||||
|
}
|
||||||
|
allocated.extend(block.allocate(scope));
|
||||||
|
}
|
||||||
|
crate::mir::FunctionDefinitionKind::Extern(_) => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Allocator {
|
||||||
|
allocations: allocated,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl mir::Block {
|
||||||
|
fn allocate<'ctx, 'a>(&self, scope: &mut AllocatorScope<'ctx, 'a>) -> Vec<Allocation> {
|
||||||
|
let mut allocated = Vec::new();
|
||||||
|
|
||||||
|
for statement in &self.statements {
|
||||||
|
allocated.extend(statement.allocate(scope));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some((_, ret_expr)) = &self.return_expression {
|
||||||
|
allocated.extend(ret_expr.allocate(scope));
|
||||||
|
}
|
||||||
|
|
||||||
|
allocated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl mir::Statement {
|
||||||
|
fn allocate<'ctx, 'a>(&self, scope: &mut AllocatorScope<'ctx, 'a>) -> Vec<Allocation> {
|
||||||
|
let mut allocated = Vec::new();
|
||||||
|
|
||||||
|
match &self.0 {
|
||||||
|
crate::mir::StmtKind::Let(named_variable_ref, _, expression) => {
|
||||||
|
allocated.extend(expression.allocate(scope));
|
||||||
|
let allocation = scope
|
||||||
|
.block
|
||||||
|
.build_named(
|
||||||
|
named_variable_ref.1.clone(),
|
||||||
|
reid_lib::Instr::Alloca(
|
||||||
|
named_variable_ref
|
||||||
|
.0
|
||||||
|
.get_type(scope.type_values, scope.types),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
allocated.push(Allocation(
|
||||||
|
named_variable_ref.1.clone(),
|
||||||
|
named_variable_ref.0.clone(),
|
||||||
|
allocation,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
crate::mir::StmtKind::Set(lhs, rhs) => {
|
||||||
|
allocated.extend(lhs.allocate(scope));
|
||||||
|
allocated.extend(rhs.allocate(scope));
|
||||||
|
}
|
||||||
|
crate::mir::StmtKind::Import(_) => {}
|
||||||
|
crate::mir::StmtKind::Expression(expression) => {
|
||||||
|
allocated.extend(expression.allocate(scope));
|
||||||
|
}
|
||||||
|
crate::mir::StmtKind::While(WhileStatement {
|
||||||
|
condition, block, ..
|
||||||
|
}) => {
|
||||||
|
allocated.extend(condition.allocate(scope));
|
||||||
|
allocated.extend(block.allocate(scope));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allocated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl mir::Expression {
|
||||||
|
fn allocate<'ctx, 'a>(&self, scope: &mut AllocatorScope<'ctx, 'a>) -> Vec<Allocation> {
|
||||||
|
let mut allocated = Vec::new();
|
||||||
|
|
||||||
|
match &self.0 {
|
||||||
|
crate::mir::ExprKind::Variable(_) => {}
|
||||||
|
crate::mir::ExprKind::Indexed(expr, _, idx) => {
|
||||||
|
allocated.extend(expr.allocate(scope));
|
||||||
|
allocated.extend(idx.allocate(scope));
|
||||||
|
}
|
||||||
|
crate::mir::ExprKind::Accessed(expression, _, _) => {
|
||||||
|
allocated.extend(expression.allocate(scope));
|
||||||
|
}
|
||||||
|
crate::mir::ExprKind::Array(expressions) => {
|
||||||
|
for expression in expressions {
|
||||||
|
allocated.extend(expression.allocate(scope));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::mir::ExprKind::Struct(_, items) => {
|
||||||
|
for (_, expression) in items {
|
||||||
|
allocated.extend(expression.allocate(scope));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::mir::ExprKind::Literal(_) => {}
|
||||||
|
crate::mir::ExprKind::BinOp(_, lhs, rhs) => {
|
||||||
|
allocated.extend(lhs.allocate(scope));
|
||||||
|
allocated.extend(rhs.allocate(scope));
|
||||||
|
}
|
||||||
|
crate::mir::ExprKind::FunctionCall(FunctionCall { parameters, .. }) => {
|
||||||
|
for param in parameters {
|
||||||
|
allocated.extend(param.allocate(scope));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::mir::ExprKind::If(IfExpression(cond, then_ex, else_ex)) => {
|
||||||
|
allocated.extend(cond.allocate(scope));
|
||||||
|
allocated.extend(then_ex.allocate(scope));
|
||||||
|
if let Some(else_ex) = else_ex.as_ref() {
|
||||||
|
allocated.extend(else_ex.allocate(scope));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::mir::ExprKind::Block(block) => {
|
||||||
|
allocated.extend(block.allocate(scope));
|
||||||
|
}
|
||||||
|
crate::mir::ExprKind::Borrow(_, _) => {}
|
||||||
|
crate::mir::ExprKind::Deref(_) => {}
|
||||||
|
crate::mir::ExprKind::CastTo(expression, _) => {
|
||||||
|
allocated.extend(expression.allocate(scope));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allocated
|
||||||
|
}
|
||||||
|
}
|
@ -158,7 +158,6 @@ impl ast::Block {
|
|||||||
StmtKind::Let(counter_var.clone(), true, start.process(module_id)),
|
StmtKind::Let(counter_var.clone(), true, start.process(module_id)),
|
||||||
counter_range.as_meta(module_id),
|
counter_range.as_meta(module_id),
|
||||||
);
|
);
|
||||||
mir_statements.push(let_statement);
|
|
||||||
|
|
||||||
let set_new = mir::Statement(
|
let set_new = mir::Statement(
|
||||||
StmtKind::Set(
|
StmtKind::Set(
|
||||||
@ -187,7 +186,7 @@ impl ast::Block {
|
|||||||
);
|
);
|
||||||
let mut block = block.into_mir(module_id);
|
let mut block = block.into_mir(module_id);
|
||||||
block.statements.push(set_new);
|
block.statements.push(set_new);
|
||||||
(
|
let while_statement = mir::Statement(
|
||||||
StmtKind::While(WhileStatement {
|
StmtKind::While(WhileStatement {
|
||||||
condition: mir::Expression(
|
condition: mir::Expression(
|
||||||
mir::ExprKind::BinOp(
|
mir::ExprKind::BinOp(
|
||||||
@ -203,8 +202,18 @@ impl ast::Block {
|
|||||||
block,
|
block,
|
||||||
meta: self.2.as_meta(module_id),
|
meta: self.2.as_meta(module_id),
|
||||||
}),
|
}),
|
||||||
self.2,
|
self.2.as_meta(module_id),
|
||||||
)
|
);
|
||||||
|
|
||||||
|
let inner_scope = StmtKind::Expression(mir::Expression(
|
||||||
|
mir::ExprKind::Block(mir::Block {
|
||||||
|
statements: vec![let_statement, while_statement],
|
||||||
|
return_expression: None,
|
||||||
|
meta: counter_range.as_meta(module_id) + end.1.as_meta(module_id),
|
||||||
|
}),
|
||||||
|
counter_range.as_meta(module_id) + end.1.as_meta(module_id),
|
||||||
|
));
|
||||||
|
(inner_scope, self.2)
|
||||||
}
|
}
|
||||||
ast::BlockLevelStatement::WhileLoop(expression, block) => (
|
ast::BlockLevelStatement::WhileLoop(expression, block) => (
|
||||||
StmtKind::While(WhileStatement {
|
StmtKind::While(WhileStatement {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{collections::HashMap, mem};
|
use std::{cell::RefCell, collections::HashMap, mem, rc::Rc};
|
||||||
|
|
||||||
use reid_lib::{
|
use reid_lib::{
|
||||||
builder::{InstructionValue, TypeValue},
|
builder::{InstructionValue, TypeValue},
|
||||||
@ -15,6 +15,7 @@ use reid_lib::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
allocator::{Allocator, AllocatorScope},
|
||||||
lexer::{FullToken, Position},
|
lexer::{FullToken, Position},
|
||||||
mir::{
|
mir::{
|
||||||
self, implement::TypeCategory, CustomTypeKey, Metadata, NamedVariableRef, SourceModuleId,
|
self, implement::TypeCategory, CustomTypeKey, Metadata, NamedVariableRef, SourceModuleId,
|
||||||
@ -76,14 +77,15 @@ pub struct Scope<'ctx, 'scope> {
|
|||||||
modules: &'scope HashMap<SourceModuleId, ModuleCodegen<'ctx>>,
|
modules: &'scope HashMap<SourceModuleId, ModuleCodegen<'ctx>>,
|
||||||
tokens: &'ctx Vec<FullToken>,
|
tokens: &'ctx Vec<FullToken>,
|
||||||
module: &'ctx Module<'ctx>,
|
module: &'ctx Module<'ctx>,
|
||||||
module_id: SourceModuleId,
|
pub(super) module_id: SourceModuleId,
|
||||||
function: &'ctx StackFunction<'ctx>,
|
function: &'ctx StackFunction<'ctx>,
|
||||||
block: Block<'ctx>,
|
pub(super) block: Block<'ctx>,
|
||||||
types: &'scope HashMap<TypeValue, TypeDefinition>,
|
pub(super) types: &'scope HashMap<TypeValue, TypeDefinition>,
|
||||||
type_values: &'scope HashMap<CustomTypeKey, TypeValue>,
|
pub(super) type_values: &'scope HashMap<CustomTypeKey, TypeValue>,
|
||||||
functions: &'scope HashMap<String, StackFunction<'ctx>>,
|
functions: &'scope HashMap<String, StackFunction<'ctx>>,
|
||||||
stack_values: HashMap<String, StackValue>,
|
stack_values: HashMap<String, StackValue>,
|
||||||
debug: Option<Debug<'ctx>>,
|
debug: Option<Debug<'ctx>>,
|
||||||
|
allocator: Rc<RefCell<Allocator>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -161,6 +163,7 @@ impl<'ctx, 'a> Scope<'ctx, 'a> {
|
|||||||
type_values: self.type_values,
|
type_values: self.type_values,
|
||||||
stack_values: self.stack_values.clone(),
|
stack_values: self.stack_values.clone(),
|
||||||
debug: self.debug.clone(),
|
debug: self.debug.clone(),
|
||||||
|
allocator: self.allocator.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,6 +178,10 @@ impl<'ctx, 'a> Scope<'ctx, 'a> {
|
|||||||
fn get_typedef(&self, key: &CustomTypeKey) -> Option<&TypeDefinition> {
|
fn get_typedef(&self, key: &CustomTypeKey) -> Option<&TypeDefinition> {
|
||||||
self.type_values.get(key).and_then(|v| self.types.get(v))
|
self.type_values.get(key).and_then(|v| self.types.get(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn allocate(&self, name: &String, ty: &TypeKind) -> Option<InstructionValue> {
|
||||||
|
self.allocator.borrow_mut().allocate(name, ty)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
||||||
@ -321,6 +328,15 @@ impl mir::Module {
|
|||||||
match &mir_function.kind {
|
match &mir_function.kind {
|
||||||
mir::FunctionDefinitionKind::Local(block, _) => {
|
mir::FunctionDefinitionKind::Local(block, _) => {
|
||||||
let mut entry = function.ir.block("entry");
|
let mut entry = function.ir.block("entry");
|
||||||
|
let mut allocator = Allocator::from(
|
||||||
|
mir_function,
|
||||||
|
&mut AllocatorScope {
|
||||||
|
block: &mut entry,
|
||||||
|
module_id: self.module_id,
|
||||||
|
types: &types,
|
||||||
|
type_values: &type_values,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// Insert debug information
|
// Insert debug information
|
||||||
let debug_scope = if let Some(location) =
|
let debug_scope = if let Some(location) =
|
||||||
@ -372,12 +388,9 @@ impl mir::Module {
|
|||||||
let param = entry
|
let param = entry
|
||||||
.build_named(format!("{}.get", arg_name), Instr::Param(i))
|
.build_named(format!("{}.get", arg_name), Instr::Param(i))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let alloca = entry
|
|
||||||
.build_named(
|
let alloca = allocator.allocate(&p_name, &p_ty).unwrap();
|
||||||
&arg_name,
|
|
||||||
Instr::Alloca(p_ty.get_type(&type_values, &types)),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
entry
|
entry
|
||||||
.build_named(format!("{}.store", arg_name), Instr::Store(alloca, param))
|
.build_named(format!("{}.store", arg_name), Instr::Store(alloca, param))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -435,6 +448,7 @@ impl mir::Module {
|
|||||||
types: &debug_types,
|
types: &debug_types,
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
|
allocator: Rc::new(RefCell::new(allocator)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let state = State::default();
|
let state = State::default();
|
||||||
@ -514,15 +528,11 @@ impl mir::Statement {
|
|||||||
let value = expression.codegen(scope, &state)?.unwrap();
|
let value = expression.codegen(scope, &state)?.unwrap();
|
||||||
|
|
||||||
let alloca = scope
|
let alloca = scope
|
||||||
.block
|
.allocate(name, &value.1)
|
||||||
.build_named(
|
|
||||||
name,
|
|
||||||
Instr::Alloca(value.1.get_type(scope.type_values, scope.types)),
|
|
||||||
)
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_location(&mut scope.block, location);
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
scope
|
let store = scope
|
||||||
.block
|
.block
|
||||||
.build_named(
|
.build_named(
|
||||||
format!("{}.store", name),
|
format!("{}.store", name),
|
||||||
@ -551,7 +561,7 @@ impl mir::Statement {
|
|||||||
flags: DwarfFlags,
|
flags: DwarfFlags,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
alloca.add_record(
|
store.add_record(
|
||||||
&mut scope.block,
|
&mut scope.block,
|
||||||
InstructionDebugRecordData {
|
InstructionDebugRecordData {
|
||||||
variable: var,
|
variable: var,
|
||||||
@ -602,9 +612,9 @@ impl mir::Statement {
|
|||||||
mir::StmtKind::While(WhileStatement {
|
mir::StmtKind::While(WhileStatement {
|
||||||
condition, block, ..
|
condition, block, ..
|
||||||
}) => {
|
}) => {
|
||||||
let condition_block = scope.function.ir.block("condition_block");
|
let condition_block = scope.function.ir.block("while.cond");
|
||||||
let condition_true_block = scope.function.ir.block("condition_true");
|
let condition_true_block = scope.function.ir.block("while.body");
|
||||||
let condition_failed_block = scope.function.ir.block("condition_failed");
|
let condition_failed_block = scope.function.ir.block("while.end");
|
||||||
|
|
||||||
scope
|
scope
|
||||||
.block
|
.block
|
||||||
@ -1179,7 +1189,7 @@ impl mir::Expression {
|
|||||||
|
|
||||||
Some({
|
Some({
|
||||||
if state.should_load {
|
if state.should_load {
|
||||||
if let TypeKind::CodegenPtr(inner) = *ptr_inner.clone() {
|
if let TypeKind::Borrow(inner, _) = *ptr_inner.clone() {
|
||||||
StackValue(
|
StackValue(
|
||||||
v.0.derive(
|
v.0.derive(
|
||||||
scope
|
scope
|
||||||
@ -1428,7 +1438,7 @@ impl mir::Literal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TypeKind {
|
impl TypeKind {
|
||||||
fn get_type(
|
pub(super) fn get_type(
|
||||||
&self,
|
&self,
|
||||||
type_vals: &HashMap<CustomTypeKey, TypeValue>,
|
type_vals: &HashMap<CustomTypeKey, TypeValue>,
|
||||||
typedefs: &HashMap<TypeValue, TypeDefinition>,
|
typedefs: &HashMap<TypeValue, TypeDefinition>,
|
||||||
|
@ -52,6 +52,7 @@ use reid_lib::{compile::CompileOutput, Context};
|
|||||||
|
|
||||||
use crate::{ast::TopLevelStatement, lexer::Token, token_stream::TokenStream};
|
use crate::{ast::TopLevelStatement, lexer::Token, token_stream::TokenStream};
|
||||||
|
|
||||||
|
mod allocator;
|
||||||
mod ast;
|
mod ast;
|
||||||
mod codegen;
|
mod codegen;
|
||||||
pub mod error_raporting;
|
pub mod error_raporting;
|
||||||
|
@ -124,3 +124,11 @@ fn struct_compiles_well() {
|
|||||||
fn loops_compiles_well() {
|
fn loops_compiles_well() {
|
||||||
test(include_str!("../../examples/loops.reid"), "test", 10);
|
test(include_str!("../../examples/loops.reid"), "test", 10);
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn ptr_hard_compiles_well() {
|
||||||
|
test(include_str!("../../examples/ptr_hard.reid"), "test", 0);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn loop_hard_compiles_well() {
|
||||||
|
test(include_str!("../../examples/loop_hard.reid"), "test", 0);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user