parent
91f2eed15a
commit
4576609b1e
@ -0,0 +1,35 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Config {
|
||||
pub builtin_functions: HashMap<String, (String, bool, usize)>,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
macro_rules! builtin_function {
|
||||
( $name:expr, $target_name:expr, $mutating:expr, $n_args:expr ) => {
|
||||
(
|
||||
String::from($name),
|
||||
(String::from($target_name), $mutating, $n_args),
|
||||
)
|
||||
};
|
||||
}
|
||||
Self {
|
||||
builtin_functions: HashMap::from([
|
||||
builtin_function!("print_flush", "printflush", false, 1),
|
||||
// TODO: write a special case for message
|
||||
builtin_function!("print_message_mission", "message mission", false, 0),
|
||||
builtin_function!("read", "read", true, 3),
|
||||
// TODO: don't use a generic operation here
|
||||
builtin_function!("write", "write", false, 3),
|
||||
builtin_function!("wait", "wait", false, 1),
|
||||
// TODO: don't use a generic operation here either
|
||||
builtin_function!("set_flag", "setflag", false, 2),
|
||||
builtin_function!("get_flag", "getflag", true, 2),
|
||||
// TODO: same thing
|
||||
builtin_function!("spawn", "spawn", false, 6),
|
||||
]),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,14 @@
|
||||
pub mod common;
|
||||
pub mod compile;
|
||||
pub mod config;
|
||||
pub mod cursor;
|
||||
pub mod optimize;
|
||||
pub mod parse;
|
||||
pub mod repr;
|
||||
pub mod translate;
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::config::Config;
|
||||
pub use crate::cursor::Cursor;
|
||||
pub use crate::repr::basic::*;
|
||||
pub use crate::repr::mlog::*;
|
||||
pub use crate::repr::operator::*;
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
use regex::Regex;
|
||||
|
||||
use super::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
/// Optimizes away unnecessary `sets`
|
||||
pub fn optimize_constant(program: MindustryProgram) -> MindustryProgram {
|
@ -1,4 +1,8 @@
|
||||
use regex::Regex;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) fn optimize_dead_code(program: MindustryProgram) -> MindustryProgram {
|
||||
let tmp_regex = Regex::new(r"__tmp_[0-9]+$").unwrap();
|
@ -1,4 +1,7 @@
|
||||
use regex::Regex;
|
||||
|
||||
use super::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
/// Tries to merge the condition in an `op` into the `jump` itself
|
||||
pub fn optimize_jump_op(program: MindustryProgram) -> MindustryProgram {
|
@ -1,6 +1,5 @@
|
||||
//! Lookaround helpers for quickly implementing optimizations
|
||||
|
||||
use super::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) enum Lookaround<T> {
|
||||
Stop(T),
|
@ -1,7 +1,3 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::*;
|
||||
|
||||
mod constant;
|
||||
pub use constant::*;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) fn replace_if<F>(program: MindustryProgram, callback: F) -> MindustryProgram
|
||||
where
|
@ -0,0 +1,41 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum BasicAstExpression {
|
||||
Integer(i64),
|
||||
Float(f64),
|
||||
Variable(String),
|
||||
String(String),
|
||||
Binary(Operator, Box<BasicAstExpression>, Box<BasicAstExpression>),
|
||||
Unary(UnaryOperator, Box<BasicAstExpression>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum BasicAstInstruction {
|
||||
JumpLabel(String),
|
||||
Assign(String, BasicAstExpression),
|
||||
Jump(String),
|
||||
IfThenElse(BasicAstExpression, BasicAstBlock, BasicAstBlock),
|
||||
Print(Vec<(BasicAstExpression, bool)>),
|
||||
CallBuiltin(String, Vec<BasicAstExpression>),
|
||||
For {
|
||||
variable: String,
|
||||
start: BasicAstExpression,
|
||||
end: BasicAstExpression,
|
||||
step: BasicAstExpression,
|
||||
instructions: BasicAstBlock,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Default)]
|
||||
pub struct BasicAstBlock {
|
||||
pub instructions: Vec<BasicAstInstruction>,
|
||||
}
|
||||
|
||||
impl BasicAstBlock {
|
||||
pub fn new(instructions: impl IntoIterator<Item = BasicAstInstruction>) -> Self {
|
||||
Self {
|
||||
instructions: instructions.into_iter().collect(),
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
use super::operator::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Operand {
|
||||
Variable(String),
|
||||
String(String),
|
||||
Integer(i64),
|
||||
Float(f64),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Operand {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Operand::Variable(name) => write!(f, "{}", name),
|
||||
Operand::String(string) => {
|
||||
let escaped = string.replace('\\', r"\\").replace('"', r#"\""#);
|
||||
write!(f, "\"{}\"", escaped)
|
||||
}
|
||||
Operand::Integer(int) => write!(f, "{}", int),
|
||||
Operand::Float(float) => write!(f, "{}", float),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MindustryOperation {
|
||||
JumpLabel(String),
|
||||
Jump(String),
|
||||
JumpIf(String, Operator, Operand, Operand),
|
||||
Operator(String, Operator, Operand, Operand),
|
||||
UnaryOperator(String, UnaryOperator, Operand),
|
||||
// TODO: add RandOperator
|
||||
Set(String, Operand),
|
||||
/// A generic operation, with the following invariants:
|
||||
/// - all of the operands are read-only
|
||||
/// - there is no external dependency to other variables
|
||||
/// - no external variable is modified
|
||||
Generic(String, Vec<Operand>),
|
||||
/// A generic, mutating operation `(name, out_name, operands)`, with the following invariants:
|
||||
/// - all of the operands are read-only
|
||||
/// - there is no external dependency to other variables, except `out_name`
|
||||
/// - only `out_name` is modified
|
||||
GenericMut(String, String, Vec<Operand>),
|
||||
}
|
||||
|
||||
impl MindustryOperation {
|
||||
pub(crate) fn operands(&self) -> Box<[&Operand]> {
|
||||
match self {
|
||||
Self::JumpIf(_label, _operator, lhs, rhs) => Box::new([lhs, rhs]),
|
||||
Self::Operator(_target, _operator, lhs, rhs) => Box::new([lhs, rhs]),
|
||||
Self::UnaryOperator(_target, _operator, value) => Box::new([value]),
|
||||
Self::Set(_target, value) => Box::new([value]),
|
||||
Self::Generic(_name, operands) => {
|
||||
operands.iter().collect::<Vec<_>>().into_boxed_slice()
|
||||
}
|
||||
Self::GenericMut(_name, _out_name, operands) => {
|
||||
operands.iter().collect::<Vec<_>>().into_boxed_slice()
|
||||
}
|
||||
_ => Box::new([]),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn operands_mut(&mut self) -> Vec<&mut Operand> {
|
||||
match self {
|
||||
Self::JumpIf(_label, _operator, lhs, rhs) => vec![lhs, rhs],
|
||||
Self::Operator(_target, _operator, lhs, rhs) => vec![lhs, rhs],
|
||||
Self::UnaryOperator(_target, _operator, value) => vec![value],
|
||||
Self::Set(_target, value) => vec![value],
|
||||
Self::Generic(_name, operands) => operands.iter_mut().collect::<Vec<_>>(),
|
||||
Self::GenericMut(_name, _out_name, operands) => operands.iter_mut().collect::<Vec<_>>(),
|
||||
_ => vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn mutates(&self, var_name: &str) -> bool {
|
||||
match self {
|
||||
MindustryOperation::JumpLabel(_)
|
||||
| MindustryOperation::Jump(_)
|
||||
| MindustryOperation::JumpIf(_, _, _, _)
|
||||
| MindustryOperation::Generic(_, _) => false,
|
||||
|
||||
MindustryOperation::Operator(out_name, _, _, _)
|
||||
| MindustryOperation::UnaryOperator(out_name, _, _)
|
||||
| MindustryOperation::Set(out_name, _)
|
||||
| MindustryOperation::GenericMut(_, out_name, _) => out_name == var_name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct MindustryProgram(pub Vec<MindustryOperation>);
|
||||
|
||||
impl MindustryProgram {
|
||||
pub fn new() -> Self {
|
||||
Self(Vec::new())
|
||||
}
|
||||
|
||||
pub fn push(&mut self, operation: MindustryOperation) {
|
||||
self.0.push(operation);
|
||||
}
|
||||
|
||||
pub fn append(&mut self, other: &mut Self) {
|
||||
self.0.append(&mut other.0);
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<MindustryOperation>> for MindustryProgram {
|
||||
fn from(value: Vec<MindustryOperation>) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
pub mod basic;
|
||||
pub mod mlog;
|
||||
pub mod operator;
|
Loading…
Reference in new issue