full rewrite, kinda works

This commit is contained in:
Mark
2023-07-28 00:33:15 +02:00
parent 16258c7a0a
commit b81dac682e
96 changed files with 3150 additions and 1982 deletions

View File

@@ -0,0 +1,25 @@
use crate::{info::Local, program};
use super::{CompInfo, MersStatement};
#[derive(Debug)]
pub struct AssignTo {
pub target: Box<dyn MersStatement>,
pub source: Box<dyn MersStatement>,
}
impl MersStatement for AssignTo {
fn has_scope(&self) -> bool {
false
}
fn compile_custom(
&self,
info: &mut crate::info::Info<super::Local>,
mut comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::assign_to::AssignTo {
target: self.target.compile(info, comp)?,
source: self.source.compile(info, comp)?,
}))
}
}

View File

@@ -0,0 +1,26 @@
use crate::{info, program};
use super::{CompInfo, MersStatement};
#[derive(Debug)]
pub struct Block {
pub statements: Vec<Box<dyn MersStatement>>,
}
impl MersStatement for Block {
fn has_scope(&self) -> bool {
true
}
fn compile_custom(
&self,
info: &mut info::Info<super::Local>,
comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::block::Block {
statements: self
.statements
.iter()
.map(|v| v.compile(info, comp))
.collect::<Result<Vec<_>, _>>()?,
}))
}
}

View File

@@ -0,0 +1,24 @@
use crate::{info, program};
use super::{CompInfo, MersStatement};
#[derive(Debug)]
pub struct Chain {
pub first: Box<dyn MersStatement>,
pub chained: Box<dyn MersStatement>,
}
impl MersStatement for Chain {
fn has_scope(&self) -> bool {
false
}
fn compile_custom(
&self,
info: &mut info::Info<super::Local>,
comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::chain::Chain {
first: self.first.compile(info, comp)?,
chained: self.chained.compile(info, comp)?,
}))
}
}

View File

@@ -0,0 +1,42 @@
use std::sync::Arc;
use crate::{
data::{self, Data},
info::Local,
program,
};
use super::{CompInfo, MersStatement};
#[derive(Debug)]
pub struct Function {
pub arg: Box<dyn MersStatement>,
pub run: Box<dyn MersStatement>,
}
impl MersStatement for Function {
fn has_scope(&self) -> bool {
// TODO: what???
false
}
fn compile_custom(
&self,
info: &mut crate::info::Info<super::Local>,
mut comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> {
comp.is_init = true;
let arg = self.arg.compile(info, comp)?;
comp.is_init = false;
let run = self.run.compile(info, comp)?;
Ok(Box::new(program::run::function::Function {
func_no_info: data::function::Function {
info: program::run::Info::neverused(),
out: Arc::new(|_i| todo!()),
run: Arc::new(move |i, info| {
data::defs::assign(i, &arg.run(info));
run.run(info)
}),
},
}))
}
}

View File

@@ -0,0 +1,31 @@
use crate::program;
use super::{CompInfo, MersStatement};
#[derive(Debug)]
pub struct If {
pub condition: Box<dyn MersStatement>,
pub on_true: Box<dyn MersStatement>,
pub on_false: Option<Box<dyn MersStatement>>,
}
impl MersStatement for If {
fn has_scope(&self) -> bool {
true
}
fn compile_custom(
&self,
info: &mut crate::info::Info<super::Local>,
comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::r#if::If {
condition: self.condition.compile(info, comp)?,
on_true: self.condition.compile(info, comp)?,
on_false: if let Some(v) = &self.on_false {
Some(v.compile(info, comp)?)
} else {
None
},
}))
}
}

View File

@@ -0,0 +1,29 @@
use crate::{info::Local, program};
use super::{CompInfo, MersStatement};
#[derive(Debug)]
pub struct InitTo {
pub target: Box<dyn MersStatement>,
pub source: Box<dyn MersStatement>,
}
impl MersStatement for InitTo {
fn has_scope(&self) -> bool {
false
}
fn compile_custom(
&self,
info: &mut crate::info::Info<super::Local>,
mut comp: CompInfo,
) -> Result<Box<dyn crate::program::run::MersStatement>, String> {
comp.is_init = true;
let target = self.target.compile(info, comp)?;
comp.is_init = false;
let source = self.source.compile(info, comp)?;
Ok(Box::new(program::run::assign_to::AssignTo {
target,
source,
}))
}
}

View File

@@ -0,0 +1,23 @@
use crate::program;
use super::{CompInfo, MersStatement};
#[derive(Debug)]
pub struct Loop {
pub inner: Box<dyn MersStatement>,
}
impl MersStatement for Loop {
fn has_scope(&self) -> bool {
true
}
fn compile_custom(
&self,
info: &mut crate::info::Info<super::Local>,
comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::r#loop::Loop {
inner: self.inner.compile(info, comp)?,
}))
}
}

View File

@@ -0,0 +1,68 @@
use std::{collections::HashMap, fmt::Debug};
use crate::info;
pub mod assign_to;
pub mod block;
pub mod chain;
pub mod function;
pub mod r#if;
pub mod init_to;
pub mod r#loop;
pub mod switch;
pub mod tuple;
pub mod value;
pub mod variable;
pub trait MersStatement: Debug {
fn has_scope(&self) -> bool;
fn compile_custom(
&self,
info: &mut Info,
comp: CompInfo,
) -> Result<Box<dyn super::run::MersStatement>, String>;
fn compile(
&self,
info: &mut Info,
comp: CompInfo,
) -> Result<Box<dyn super::run::MersStatement>, String> {
if self.has_scope() {
info.create_scope();
}
let o = self.compile_custom(info, comp);
if self.has_scope() {
info.end_scope();
}
o
}
}
#[derive(Clone, Copy)]
pub struct CompInfo {
is_init: bool,
}
impl Default for CompInfo {
fn default() -> Self {
Self { is_init: false }
}
}
pub type Info = info::Info<Local>;
#[derive(Default, Clone, Debug)]
pub struct Local {
vars: HashMap<String, (usize, usize)>,
}
impl info::Local for Local {
type VariableIdentifier = String;
type VariableData = (usize, usize);
fn init_var(&mut self, id: Self::VariableIdentifier, value: Self::VariableData) {
self.vars.insert(id, value);
}
fn get_var(&self, id: &Self::VariableIdentifier) -> Option<&Self::VariableData> {
self.vars.get(id)
}
fn get_var_mut(&mut self, id: &Self::VariableIdentifier) -> Option<&mut Self::VariableData> {
self.vars.get_mut(id)
}
}

View File

@@ -0,0 +1,27 @@
use crate::data::Type;
use super::{CompInfo, MersStatement};
#[derive(Debug)]
pub struct Switch {
source: Box<dyn MersStatement>,
arms: Vec<SwitchArm>,
}
#[derive(Debug)]
pub struct SwitchArm {
requires_type: Type,
}
impl MersStatement for Switch {
fn has_scope(&self) -> bool {
true
}
fn compile_custom(
&self,
info: &mut crate::info::Info<super::Local>,
comp: CompInfo,
) -> Result<Box<dyn crate::program::run::MersStatement>, String> {
todo!()
}
}

View File

@@ -0,0 +1,26 @@
use crate::{info, program};
use super::{CompInfo, MersStatement};
#[derive(Debug)]
pub struct Tuple {
pub elems: Vec<Box<dyn MersStatement>>,
}
impl MersStatement for Tuple {
fn has_scope(&self) -> bool {
false
}
fn compile_custom(
&self,
info: &mut info::Info<super::Local>,
comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::tuple::Tuple {
elems: self
.elems
.iter()
.map(|v| v.compile(info, comp))
.collect::<Result<Vec<_>, _>>()?,
}))
}
}

View File

@@ -0,0 +1,21 @@
use crate::{data::Data, program};
use super::{CompInfo, MersStatement};
#[derive(Debug)]
pub struct Value(pub Data);
impl MersStatement for Value {
fn has_scope(&self) -> bool {
false
}
fn compile_custom(
&self,
info: &mut crate::info::Info<super::Local>,
comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::value::Value {
val: self.0.clone(),
}))
}
}

View File

@@ -0,0 +1,38 @@
use crate::{info::Local, program};
use super::{CompInfo, MersStatement};
#[derive(Debug)]
pub struct Variable {
pub is_ref: bool,
pub var: String,
}
impl MersStatement for Variable {
fn has_scope(&self) -> bool {
false
}
fn compile_custom(
&self,
info: &mut crate::info::Info<super::Local>,
comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> {
if comp.is_init {
info.init_var(
self.var.clone(),
(
info.scopes.len() - 1,
info.scopes.last().unwrap().vars.len(),
),
)
}
Ok(Box::new(program::run::variable::Variable {
is_ref: comp.is_init || self.is_ref,
var: if let Some(v) = info.get_var(&self.var) {
*v
} else {
return Err(format!("No variable named '{}' found!", self.var));
},
}))
}
}