maybe migration
This commit is contained in:
parent
08cb1109c7
commit
c51a7fd0fc
6 changed files with 113 additions and 15 deletions
|
|
@ -204,7 +204,8 @@ impl Record {
|
|||
}
|
||||
}
|
||||
|
||||
pub const UNIT: Expr = Expr::Value(Value::Record(Record(BTreeMap::new())));
|
||||
pub const UNIT_VALUE: Value = Value::Record(Record(BTreeMap::new()));
|
||||
pub const UNIT: Expr = Expr::Value(UNIT_VALUE);
|
||||
|
||||
#[derive(PartialEq, Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
|
|
|
|||
|
|
@ -5,29 +5,44 @@ use std::collections::BTreeMap;
|
|||
|
||||
use crate::ast;
|
||||
|
||||
pub fn run(
|
||||
program: ast::Program,
|
||||
pub fn global_env_name() -> ast::EnvName {
|
||||
ast::EnvName("global".to_string())
|
||||
}
|
||||
|
||||
pub fn setup(program: ast::Program) -> Result<State, Error> {
|
||||
let mut state = State::new(global_env_name().0.clone());
|
||||
|
||||
defs_to_env(program.0, &global_env_name(), &mut state)?;
|
||||
Ok(state)
|
||||
}
|
||||
|
||||
pub fn interpret(
|
||||
state: &mut State,
|
||||
func: ast::Name,
|
||||
args: Vec<ast::Expr>,
|
||||
) -> Result<ast::Value, Error> {
|
||||
let env_name = ast::EnvName("global".to_string());
|
||||
let mut state = State::new("global".into());
|
||||
|
||||
defs_to_env(program.0, &env_name, &mut state)?;
|
||||
|
||||
let main = ast::Expr::Value(state.envs.get(&env_name)?.get(&func)?.clone());
|
||||
let main = ast::Expr::Value(state.envs.get(&global_env_name())?.get(&func)?.clone());
|
||||
|
||||
let expr = ast::Expr::FunCall {
|
||||
func: Box::new(main),
|
||||
args,
|
||||
};
|
||||
|
||||
let env: Env = state.envs.get(&env_name)?.clone();
|
||||
let result = eval_expr(&env, &mut state, &expr)?;
|
||||
let env: Env = state.envs.get(&global_env_name())?.clone();
|
||||
let result = eval_expr(&env, state, &expr)?;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn run(
|
||||
program: ast::Program,
|
||||
func: ast::Name,
|
||||
args: Vec<ast::Expr>,
|
||||
) -> Result<ast::Value, Error> {
|
||||
let mut state = setup(program)?;
|
||||
interpret(&mut state, func, args)
|
||||
}
|
||||
|
||||
enum StatementResult {
|
||||
Result(ast::Value),
|
||||
Return(ast::Value),
|
||||
|
|
@ -230,6 +245,33 @@ fn defs_to_env(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn value_to_stadnalone_expr(state: &State, value: ast::Value) -> Result<ast::Expr, String> {
|
||||
match value {
|
||||
ast::Value::Ref(reference) => {
|
||||
let value = state.variables.get(&reference).clone();
|
||||
value_to_stadnalone_expr(state, value)
|
||||
}
|
||||
ast::Value::Vector(vector) => {
|
||||
let mut vec = Vec::with_capacity(vector.0.len());
|
||||
for reference in vector.0 {
|
||||
let expr = value_to_stadnalone_expr(state, ast::Value::Ref(reference))?;
|
||||
vec.push(expr);
|
||||
}
|
||||
Ok(ast::Expr::Vector(vec))
|
||||
}
|
||||
ast::Value::Record(record) => {
|
||||
let mut map = BTreeMap::new();
|
||||
for (field, reference) in record.0 {
|
||||
let expr = value_to_stadnalone_expr(state, ast::Value::Ref(reference))?;
|
||||
map.insert(field.clone(), expr);
|
||||
}
|
||||
Ok(ast::Expr::Record(map))
|
||||
}
|
||||
ast::Value::Closure { .. } => Err("Closure migration not supported".into()),
|
||||
_ => Ok(ast::Expr::Value(value)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@ pub mod interpret;
|
|||
pub mod types;
|
||||
|
||||
pub use interpret::*;
|
||||
pub use types::*;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use ayin::ast;
|
||||
use ayin::runtime::*;
|
||||
use macroquad::prelude::*;
|
||||
|
||||
|
|
@ -16,7 +17,7 @@ async fn main() {
|
|||
env_logger::init();
|
||||
info!("Hello, 👁️🗨️!");
|
||||
|
||||
let mut state = setup().await;
|
||||
let mut state = setup(ast::Program(vec![])).await;
|
||||
|
||||
loop {
|
||||
let events = fetch_events();
|
||||
|
|
|
|||
|
|
@ -1,13 +1,64 @@
|
|||
use super::types::*;
|
||||
use crate::ast;
|
||||
use crate::interpret;
|
||||
use macroquad::prelude::*;
|
||||
|
||||
pub async fn setup() -> State {
|
||||
pub async fn setup(code: ast::Program) -> State {
|
||||
let font = load_ttf_font("./assets/fonts/monogram.ttf").await.unwrap();
|
||||
|
||||
let mut state = match interpret::setup(code) {
|
||||
Ok(state) => state,
|
||||
Err(err) => {
|
||||
println!("Error: {}", err);
|
||||
interpret::State::new("game".into())
|
||||
}
|
||||
};
|
||||
let game_state = match interpret::interpret(&mut state, "setup".into(), vec![]) {
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
println!("Error: {}", err);
|
||||
ast::UNIT_VALUE
|
||||
}
|
||||
};
|
||||
|
||||
State {
|
||||
assets: Assets { font },
|
||||
code: ast::Program(vec![]),
|
||||
state,
|
||||
game_state,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn migrate(mut state: State, code: ast::Program) -> State {
|
||||
match interpret::setup(code) {
|
||||
Err(err) => {
|
||||
println!("Error: {}", err);
|
||||
state
|
||||
}
|
||||
Ok(mut new_program_state) => {
|
||||
match interpret::value_to_stadnalone_expr(&state.state, state.game_state.clone()) {
|
||||
Err(err) => {
|
||||
println!("Error: {}", err);
|
||||
state
|
||||
}
|
||||
Ok(expanded_game_state) => {
|
||||
match interpret::interpret(
|
||||
&mut new_program_state,
|
||||
"migrate".into(),
|
||||
vec![expanded_game_state],
|
||||
) {
|
||||
Err(err) => {
|
||||
println!("Error: {}", err);
|
||||
state
|
||||
}
|
||||
Ok(result) => {
|
||||
state.game_state = result;
|
||||
state.state = new_program_state;
|
||||
state
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
use crate::ast;
|
||||
use crate::interpret;
|
||||
use macroquad::prelude::*;
|
||||
|
||||
pub struct State {
|
||||
pub assets: Assets,
|
||||
pub code: ast::Program,
|
||||
pub state: interpret::types::State,
|
||||
pub game_state: ast::Value,
|
||||
}
|
||||
|
||||
pub struct Assets {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue