Make macros generate globals
This commit is contained in:
parent
50a875ad21
commit
735c3231b1
@ -128,6 +128,7 @@ impl ast::Module {
|
|||||||
imports,
|
imports,
|
||||||
associated_functions,
|
associated_functions,
|
||||||
functions,
|
functions,
|
||||||
|
globals: Vec::new(),
|
||||||
path: self.path.clone(),
|
path: self.path.clone(),
|
||||||
is_main: self.is_main,
|
is_main: self.is_main,
|
||||||
tokens: self.tokens,
|
tokens: self.tokens,
|
||||||
|
@ -3,6 +3,7 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
|||||||
use allocator::{Allocator, AllocatorScope};
|
use allocator::{Allocator, AllocatorScope};
|
||||||
use intrinsics::*;
|
use intrinsics::*;
|
||||||
use reid_lib::{
|
use reid_lib::{
|
||||||
|
builder::ConstantValue,
|
||||||
compile::CompiledModule,
|
compile::CompiledModule,
|
||||||
debug_information::{
|
debug_information::{
|
||||||
DebugFileData, DebugLexicalScope, DebugLocalVariable, DebugLocation, DebugMetadata, DebugRecordKind,
|
DebugFileData, DebugLexicalScope, DebugLocalVariable, DebugLocation, DebugMetadata, DebugRecordKind,
|
||||||
@ -96,6 +97,14 @@ impl Default for State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl mir::GlobalKind {
|
||||||
|
fn codegen<'ctx>(&'ctx self, context: &'ctx Context, module: &Module) -> Result<ConstantValue, ErrorKind> {
|
||||||
|
Ok(match self {
|
||||||
|
mir::GlobalKind::Literal(literal) => module.add_constant(literal.as_const_kind()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl mir::Module {
|
impl mir::Module {
|
||||||
fn codegen<'ctx>(
|
fn codegen<'ctx>(
|
||||||
&'ctx self,
|
&'ctx self,
|
||||||
@ -105,8 +114,10 @@ impl mir::Module {
|
|||||||
let mut module = context.module(&self.name, self.is_main);
|
let mut module = context.module(&self.name, self.is_main);
|
||||||
let tokens = &self.tokens;
|
let tokens = &self.tokens;
|
||||||
|
|
||||||
let const_value = module.add_constant(ConstValueKind::I128(132));
|
for global in &self.globals {
|
||||||
module.add_global("some_global", const_value);
|
let const_value = global.kind.codegen(context, &module)?;
|
||||||
|
module.add_global(&global.name, const_value);
|
||||||
|
}
|
||||||
|
|
||||||
let (debug, compile_unit) = if let Some(path) = &self.path {
|
let (debug, compile_unit) = if let Some(path) = &self.path {
|
||||||
module.create_debug_info(DebugFileData {
|
module.create_debug_info(DebugFileData {
|
||||||
|
@ -34,11 +34,13 @@ impl mir::CmpOperator {
|
|||||||
|
|
||||||
impl mir::Literal {
|
impl mir::Literal {
|
||||||
pub(super) fn as_const(&self, block: &mut Block) -> InstructionValue {
|
pub(super) fn as_const(&self, block: &mut Block) -> InstructionValue {
|
||||||
block.build_named(format!("{}", self), self.as_const_kind()).unwrap()
|
block
|
||||||
|
.build_named(format!("{}", self), Instr::Constant(self.as_const_kind()))
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn as_const_kind(&self) -> Instr {
|
pub(super) fn as_const_kind(&self) -> ConstValueKind {
|
||||||
Instr::Constant(match self.clone() {
|
match self.clone() {
|
||||||
mir::Literal::I8(val) => ConstValueKind::I8(val),
|
mir::Literal::I8(val) => ConstValueKind::I8(val),
|
||||||
mir::Literal::I16(val) => ConstValueKind::I16(val),
|
mir::Literal::I16(val) => ConstValueKind::I16(val),
|
||||||
mir::Literal::I32(val) => ConstValueKind::I32(val),
|
mir::Literal::I32(val) => ConstValueKind::I32(val),
|
||||||
@ -61,7 +63,7 @@ impl mir::Literal {
|
|||||||
mir::Literal::F128(val) => ConstValueKind::F128(val),
|
mir::Literal::F128(val) => ConstValueKind::F128(val),
|
||||||
mir::Literal::F128PPC(val) => ConstValueKind::F128PPC(val),
|
mir::Literal::F128PPC(val) => ConstValueKind::F128PPC(val),
|
||||||
mir::Literal::Char(c) => ConstValueKind::U8(c as u8),
|
mir::Literal::Char(c) => ConstValueKind::U8(c as u8),
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::mir::{self, FunctionCall, IfExpression, WhileStatement};
|
use crate::mir::{self, FunctionCall, GlobalKind, GlobalValue, IfExpression, Literal, WhileStatement};
|
||||||
|
|
||||||
use super::pass::{Pass, PassResult, PassState};
|
use super::pass::{Pass, PassResult, PassState};
|
||||||
|
|
||||||
pub trait MacroFunction: std::fmt::Debug {
|
pub trait MacroFunction: std::fmt::Debug {
|
||||||
fn generate<'ctx, 'a>(&self, params: &[mir::Literal]) -> Result<mir::ExprKind, ErrorKind>;
|
fn generate<'ctx, 'a>(&self, params: &[mir::Literal]) -> Result<(Vec<GlobalValue>, mir::ExprKind), ErrorKind>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
@ -36,52 +36,57 @@ impl Pass for MacroPass {
|
|||||||
|
|
||||||
fn module(&mut self, module: &mut mir::Module, mut state: PassState<Self::Data, Self::TError>) -> PassResult {
|
fn module(&mut self, module: &mut mir::Module, mut state: PassState<Self::Data, Self::TError>) -> PassResult {
|
||||||
for function in &mut module.functions {
|
for function in &mut module.functions {
|
||||||
match &mut function.kind {
|
let globals = match &mut function.kind {
|
||||||
mir::FunctionDefinitionKind::Local(block, _) => block.gen_macros(self, &mut state)?,
|
mir::FunctionDefinitionKind::Local(block, _) => block.gen_macros(self, &mut state),
|
||||||
_ => {}
|
_ => Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.globals.extend(globals);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mir::Block {
|
impl mir::Block {
|
||||||
fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> PassResult {
|
fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> Vec<GlobalValue> {
|
||||||
|
let mut globals = Vec::new();
|
||||||
for statement in &mut self.statements {
|
for statement in &mut self.statements {
|
||||||
statement.gen_macros(data, state)?;
|
globals.extend(statement.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
if let Some((_, Some(return_expr))) = &mut self.return_expression {
|
if let Some((_, Some(return_expr))) = &mut self.return_expression {
|
||||||
return_expr.gen_macros(data, state)?;
|
globals.extend(return_expr.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
Ok(())
|
globals
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mir::Statement {
|
impl mir::Statement {
|
||||||
fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> PassResult {
|
fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> Vec<GlobalValue> {
|
||||||
|
let mut globals = Vec::new();
|
||||||
match &mut self.0 {
|
match &mut self.0 {
|
||||||
mir::StmtKind::Let(.., expr) => {
|
mir::StmtKind::Let(.., expr) => {
|
||||||
expr.gen_macros(data, state)?;
|
globals.extend(expr.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
mir::StmtKind::Set(lhs, rhs) => {
|
mir::StmtKind::Set(lhs, rhs) => {
|
||||||
lhs.gen_macros(data, state)?;
|
globals.extend(lhs.gen_macros(data, state));
|
||||||
rhs.gen_macros(data, state)?;
|
globals.extend(rhs.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
mir::StmtKind::Import(_) => {}
|
mir::StmtKind::Import(_) => {}
|
||||||
mir::StmtKind::Expression(expr) => {
|
mir::StmtKind::Expression(expr) => {
|
||||||
expr.gen_macros(data, state)?;
|
globals.extend(expr.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
mir::StmtKind::While(WhileStatement { condition, block, .. }) => {
|
mir::StmtKind::While(WhileStatement { condition, block, .. }) => {
|
||||||
condition.gen_macros(data, state)?;
|
globals.extend(condition.gen_macros(data, state));
|
||||||
block.gen_macros(data, state)?;
|
globals.extend(block.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(())
|
globals
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mir::Expression {
|
impl mir::Expression {
|
||||||
fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> PassResult {
|
fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> Vec<GlobalValue> {
|
||||||
|
let mut globals = Vec::new();
|
||||||
match &mut self.0 {
|
match &mut self.0 {
|
||||||
mir::ExprKind::FunctionCall(function_call) => {
|
mir::ExprKind::FunctionCall(function_call) => {
|
||||||
if function_call.is_macro {
|
if function_call.is_macro {
|
||||||
@ -93,13 +98,15 @@ impl mir::Expression {
|
|||||||
_ => state.note_errors(&vec![ErrorKind::InvalidMacroArgs], param.1),
|
_ => state.note_errors(&vec![ErrorKind::InvalidMacroArgs], param.1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*self = state.or_else(
|
let (generated_globals, expr) = state.or_else(
|
||||||
existing_macro
|
existing_macro
|
||||||
.generate(&literals)
|
.generate(&literals)
|
||||||
.map(|kind| mir::Expression(kind, self.1)),
|
.map(|(globals, kind)| (globals, mir::Expression(kind, self.1))),
|
||||||
self.clone(),
|
(Vec::new(), self.clone()),
|
||||||
self.1,
|
self.1,
|
||||||
);
|
);
|
||||||
|
globals.extend(generated_globals);
|
||||||
|
*self = expr;
|
||||||
} else {
|
} else {
|
||||||
state.note_errors(
|
state.note_errors(
|
||||||
&vec![ErrorKind::NoSuchMacro(function_call.name.clone())],
|
&vec![ErrorKind::NoSuchMacro(function_call.name.clone())],
|
||||||
@ -110,26 +117,26 @@ impl mir::Expression {
|
|||||||
}
|
}
|
||||||
mir::ExprKind::Variable(_) => {}
|
mir::ExprKind::Variable(_) => {}
|
||||||
mir::ExprKind::Indexed(expression, _, expression1) => {
|
mir::ExprKind::Indexed(expression, _, expression1) => {
|
||||||
expression.gen_macros(data, state)?;
|
globals.extend(expression.gen_macros(data, state));
|
||||||
expression1.gen_macros(data, state)?;
|
globals.extend(expression1.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
mir::ExprKind::Accessed(expression, ..) => {
|
mir::ExprKind::Accessed(expression, ..) => {
|
||||||
expression.gen_macros(data, state)?;
|
globals.extend(expression.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
mir::ExprKind::Array(expressions) => {
|
mir::ExprKind::Array(expressions) => {
|
||||||
for expression in expressions {
|
for expression in expressions {
|
||||||
expression.gen_macros(data, state)?;
|
globals.extend(expression.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::ExprKind::Struct(_, items) => {
|
mir::ExprKind::Struct(_, items) => {
|
||||||
for item in items {
|
for item in items {
|
||||||
item.1.gen_macros(data, state)?;
|
globals.extend(item.1.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::ExprKind::Literal(_) => {}
|
mir::ExprKind::Literal(_) => {}
|
||||||
mir::ExprKind::BinOp(_, expression, expression1, _) => {
|
mir::ExprKind::BinOp(_, expression, expression1, _) => {
|
||||||
expression.gen_macros(data, state)?;
|
globals.extend(expression.gen_macros(data, state));
|
||||||
expression1.gen_macros(data, state)?;
|
globals.extend(expression1.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
mir::ExprKind::AssociatedFunctionCall(
|
mir::ExprKind::AssociatedFunctionCall(
|
||||||
_,
|
_,
|
||||||
@ -138,30 +145,30 @@ impl mir::Expression {
|
|||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
for expression in parameters {
|
for expression in parameters {
|
||||||
expression.gen_macros(data, state)?;
|
globals.extend(expression.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::ExprKind::If(IfExpression(cond, lhs, rhs)) => {
|
mir::ExprKind::If(IfExpression(cond, lhs, rhs)) => {
|
||||||
cond.gen_macros(data, state)?;
|
globals.extend(cond.gen_macros(data, state));
|
||||||
lhs.gen_macros(data, state)?;
|
globals.extend(lhs.gen_macros(data, state));
|
||||||
if let Some(rhs) = rhs.as_mut() {
|
if let Some(rhs) = rhs.as_mut() {
|
||||||
rhs.gen_macros(data, state)?;
|
globals.extend(rhs.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::ExprKind::Block(block) => {
|
mir::ExprKind::Block(block) => {
|
||||||
block.gen_macros(data, state)?;
|
globals.extend(block.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
mir::ExprKind::Borrow(expression, _) => {
|
mir::ExprKind::Borrow(expression, _) => {
|
||||||
expression.gen_macros(data, state)?;
|
globals.extend(expression.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
mir::ExprKind::Deref(expression) => {
|
mir::ExprKind::Deref(expression) => {
|
||||||
expression.gen_macros(data, state)?;
|
globals.extend(expression.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
mir::ExprKind::CastTo(expression, _) => {
|
mir::ExprKind::CastTo(expression, _) => {
|
||||||
expression.gen_macros(data, state)?;
|
globals.extend(expression.gen_macros(data, state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
globals
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,9 +183,13 @@ pub fn form_macros() -> HashMap<String, Box<dyn MacroFunction>> {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TestMacro;
|
pub struct TestMacro;
|
||||||
impl MacroFunction for TestMacro {
|
impl MacroFunction for TestMacro {
|
||||||
fn generate<'ctx, 'a>(&self, _: &[mir::Literal]) -> Result<mir::ExprKind, ErrorKind> {
|
fn generate<'ctx, 'a>(&self, _: &[mir::Literal]) -> Result<(Vec<GlobalValue>, mir::ExprKind), ErrorKind> {
|
||||||
Ok(mir::ExprKind::Literal(mir::Literal::Vague(mir::VagueLiteral::Number(
|
Ok((
|
||||||
5,
|
vec![GlobalValue {
|
||||||
))))
|
name: "sometestglobalvalue".to_owned(),
|
||||||
|
kind: GlobalKind::Literal(Literal::I16(12)),
|
||||||
|
}],
|
||||||
|
mir::ExprKind::Literal(mir::Literal::Vague(mir::VagueLiteral::Number(5))),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,11 +421,23 @@ pub struct Module {
|
|||||||
pub functions: Vec<FunctionDefinition>,
|
pub functions: Vec<FunctionDefinition>,
|
||||||
pub typedefs: Vec<TypeDefinition>,
|
pub typedefs: Vec<TypeDefinition>,
|
||||||
pub binop_defs: Vec<BinopDefinition>,
|
pub binop_defs: Vec<BinopDefinition>,
|
||||||
|
pub globals: Vec<GlobalValue>,
|
||||||
pub path: Option<PathBuf>,
|
pub path: Option<PathBuf>,
|
||||||
pub tokens: Vec<FullToken>,
|
pub tokens: Vec<FullToken>,
|
||||||
pub is_main: bool,
|
pub is_main: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GlobalValue {
|
||||||
|
pub name: String,
|
||||||
|
pub kind: GlobalKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum GlobalKind {
|
||||||
|
Literal(Literal),
|
||||||
|
}
|
||||||
|
|
||||||
pub type ModuleMap = HashMap<SourceModuleId, Module>;
|
pub type ModuleMap = HashMap<SourceModuleId, Module>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
Loading…
Reference in New Issue
Block a user