From a4457e20cf7ad087549a3253649d003ef0dd378f Mon Sep 17 00:00:00 2001 From: Adrien Burgun Date: Thu, 5 Oct 2023 11:58:15 +0200 Subject: [PATCH] :pencil: Rename builtin_functions to builtin_routines --- GUIDE.md | 46 +++++++++++++++++++++++++++++++++++++++++++- src/config.rs | 8 ++++---- src/parse/ast.rs | 4 ++-- src/translate/mod.rs | 2 +- 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/GUIDE.md b/GUIDE.md index 12418cc..0d2a465 100644 --- a/GUIDE.md +++ b/GUIDE.md @@ -208,4 +208,48 @@ LOOP ## Subroutines -Subroutines allow you to execute the same piece of code from +Subroutines allow you to jump to a point in your code, and return back to where you entered the subroutine. +This allows you to re-use a piece of code, without duplicating it. + +```basic +color = "white" +amount = 0 +GOSUB display + +WHILE true + READ(amount, cell1, 0) + IF amount > 0 THEN + color = "green" + GOSUB display + ELSE + color = "red" + GOSUB display + END IF +WEND + +display: + PRINT "Amount: [", color, "]", amount, "[white]" + PRINT_FLUSH(message1) + RETURN +``` + +As of now, subroutines save their return point in a numeric variable, using modulus arithmetic to pack many returns in one. +This allows for 17 nested subroutine calls, before the "return stack" overflows. +In most program however, this limitation shouldn't cause issues, unless if you forgot a `RETURN` or cause an infinite amount of recursive `GOSUB`s. + +The "return stack" is cleared at the beginning of the generated program. + +## Interacting with the world + +`mlog` provides several ways for processors to interact with the in-game world, which are reflected in MinBasic using functions: + + diff --git a/src/config.rs b/src/config.rs index 9d5d617..8e852b2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,10 +7,10 @@ use crate::{ }; pub struct Config { - pub builtin_functions: HashMap, bool, usize)>, + pub builtin_routines: HashMap, bool, usize)>, /// Used for functions like `print_flush_world` - pub special_functions: HashMap< + pub special_routines: HashMap< String, Box, Position) -> Result>, >, @@ -120,7 +120,7 @@ impl Default for Config { ); Self { - builtin_functions: HashMap::from([ + builtin_routines: HashMap::from([ builtin_function!("print_flush", None, false, 1), builtin_function!("read", None, true, 3), builtin_function!("write", None, false, 3), @@ -131,7 +131,7 @@ impl Default for Config { // TODO: same thing builtin_function!("spawn", Some("spawn"), false, 6), ]), - special_functions, + special_routines: special_functions, } } } diff --git a/src/parse/ast.rs b/src/parse/ast.rs index deecca7..67beb7c 100644 --- a/src/parse/ast.rs +++ b/src/parse/ast.rs @@ -329,10 +329,10 @@ pub fn build_ast( let lowercase_fn_name = fn_name.to_lowercase(); - if let Some(translation_fn) = config.special_functions.get(&lowercase_fn_name) { + if let Some(translation_fn) = config.special_routines.get(&lowercase_fn_name) { instructions.push(translation_fn(arguments, span)?); } else if let Some((_, mutating, n_args)) = - config.builtin_functions.get(&lowercase_fn_name) + config.builtin_routines.get(&lowercase_fn_name) { if *mutating { let BasicAstExpression::Variable(_) = &arguments[0] else { diff --git a/src/translate/mod.rs b/src/translate/mod.rs index 4e10f35..b118916 100644 --- a/src/translate/mod.rs +++ b/src/translate/mod.rs @@ -397,7 +397,7 @@ pub fn translate_ast( ) ), Instr::CallBuiltin(name, arguments) => { - let Some((Some(target_name), mutating, _)) = config.builtin_functions.get(name) + let Some((Some(target_name), mutating, _)) = config.builtin_routines.get(name) else { unreachable!("CallBuiltin constructed with unknown function name"); };