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)]
|
#[derive(PartialEq, Debug, thiserror::Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
|
|
||||||
|
|
@ -5,29 +5,44 @@ use std::collections::BTreeMap;
|
||||||
|
|
||||||
use crate::ast;
|
use crate::ast;
|
||||||
|
|
||||||
pub fn run(
|
pub fn global_env_name() -> ast::EnvName {
|
||||||
program: ast::Program,
|
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,
|
func: ast::Name,
|
||||||
args: Vec<ast::Expr>,
|
args: Vec<ast::Expr>,
|
||||||
) -> Result<ast::Value, Error> {
|
) -> Result<ast::Value, Error> {
|
||||||
let env_name = ast::EnvName("global".to_string());
|
let main = ast::Expr::Value(state.envs.get(&global_env_name())?.get(&func)?.clone());
|
||||||
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 expr = ast::Expr::FunCall {
|
let expr = ast::Expr::FunCall {
|
||||||
func: Box::new(main),
|
func: Box::new(main),
|
||||||
args,
|
args,
|
||||||
};
|
};
|
||||||
|
|
||||||
let env: Env = state.envs.get(&env_name)?.clone();
|
let env: Env = state.envs.get(&global_env_name())?.clone();
|
||||||
let result = eval_expr(&env, &mut state, &expr)?;
|
let result = eval_expr(&env, state, &expr)?;
|
||||||
|
|
||||||
Ok(result)
|
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 {
|
enum StatementResult {
|
||||||
Result(ast::Value),
|
Result(ast::Value),
|
||||||
Return(ast::Value),
|
Return(ast::Value),
|
||||||
|
|
@ -230,6 +245,33 @@ fn defs_to_env(
|
||||||
Ok(())
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
|
|
@ -4,3 +4,4 @@ pub mod interpret;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
pub use interpret::*;
|
pub use interpret::*;
|
||||||
|
pub use types::*;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use ayin::ast;
|
||||||
use ayin::runtime::*;
|
use ayin::runtime::*;
|
||||||
use macroquad::prelude::*;
|
use macroquad::prelude::*;
|
||||||
|
|
||||||
|
|
@ -16,7 +17,7 @@ async fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
info!("Hello, 👁️🗨️!");
|
info!("Hello, 👁️🗨️!");
|
||||||
|
|
||||||
let mut state = setup().await;
|
let mut state = setup(ast::Program(vec![])).await;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let events = fetch_events();
|
let events = fetch_events();
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,64 @@
|
||||||
use super::types::*;
|
use super::types::*;
|
||||||
use crate::ast;
|
use crate::ast;
|
||||||
|
use crate::interpret;
|
||||||
use macroquad::prelude::*;
|
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 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 {
|
State {
|
||||||
assets: Assets { font },
|
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::ast;
|
||||||
|
use crate::interpret;
|
||||||
use macroquad::prelude::*;
|
use macroquad::prelude::*;
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub assets: Assets,
|
pub assets: Assets,
|
||||||
pub code: ast::Program,
|
pub state: interpret::types::State,
|
||||||
|
pub game_state: ast::Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Assets {
|
pub struct Assets {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue