mirror of
https://github.com/Dummi26/mers.git
synced 2025-12-28 17:16:31 +01:00
full rewrite, kinda works
This commit is contained in:
25
mers_lib/src/program/parsed/assign_to.rs
Executable file
25
mers_lib/src/program/parsed/assign_to.rs
Executable 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)?,
|
||||
}))
|
||||
}
|
||||
}
|
||||
26
mers_lib/src/program/parsed/block.rs
Executable file
26
mers_lib/src/program/parsed/block.rs
Executable 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<_>, _>>()?,
|
||||
}))
|
||||
}
|
||||
}
|
||||
24
mers_lib/src/program/parsed/chain.rs
Executable file
24
mers_lib/src/program/parsed/chain.rs
Executable 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)?,
|
||||
}))
|
||||
}
|
||||
}
|
||||
42
mers_lib/src/program/parsed/function.rs
Executable file
42
mers_lib/src/program/parsed/function.rs
Executable 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)
|
||||
}),
|
||||
},
|
||||
}))
|
||||
}
|
||||
}
|
||||
31
mers_lib/src/program/parsed/if.rs
Executable file
31
mers_lib/src/program/parsed/if.rs
Executable 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
|
||||
},
|
||||
}))
|
||||
}
|
||||
}
|
||||
29
mers_lib/src/program/parsed/init_to.rs
Executable file
29
mers_lib/src/program/parsed/init_to.rs
Executable 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,
|
||||
}))
|
||||
}
|
||||
}
|
||||
23
mers_lib/src/program/parsed/loop.rs
Executable file
23
mers_lib/src/program/parsed/loop.rs
Executable 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)?,
|
||||
}))
|
||||
}
|
||||
}
|
||||
68
mers_lib/src/program/parsed/mod.rs
Executable file
68
mers_lib/src/program/parsed/mod.rs
Executable 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)
|
||||
}
|
||||
}
|
||||
27
mers_lib/src/program/parsed/switch.rs
Executable file
27
mers_lib/src/program/parsed/switch.rs
Executable 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!()
|
||||
}
|
||||
}
|
||||
26
mers_lib/src/program/parsed/tuple.rs
Executable file
26
mers_lib/src/program/parsed/tuple.rs
Executable 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<_>, _>>()?,
|
||||
}))
|
||||
}
|
||||
}
|
||||
21
mers_lib/src/program/parsed/value.rs
Executable file
21
mers_lib/src/program/parsed/value.rs
Executable 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(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
38
mers_lib/src/program/parsed/variable.rs
Executable file
38
mers_lib/src/program/parsed/variable.rs
Executable 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));
|
||||
},
|
||||
}))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user