Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A45 Feature: Functions shall have local variables #31

Merged
merged 1 commit into from
Sep 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/modules/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ pub struct Block {
}

impl Block {
// Get whether this block is empty
pub fn is_empty(&self) -> bool {
self.statements.is_empty()
}

// Push a parsed statement into the block
pub fn push_statement(&mut self, statement: Statement) {
self.statements.push(statement);
}
Expand Down
3 changes: 3 additions & 0 deletions src/modules/function/invocation_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ fn run_function_with_args(meta: &mut ParserMetadata, name: &str, args: &[Type])
let mut block = Block::new();
// Create a new parser metadata specific for the function parsing context
let mut new_meta = meta.clone();
let function_ctx = new_meta.function_ctx;
new_meta.expr = function.body.clone();
new_meta.set_index(0);
new_meta.function_ctx = true;
// Create a sub context for new variables
new_meta.mem.push_scope();
for (kind, (name, _generic)) in args.iter().zip(function.args.iter()) {
Expand All @@ -20,6 +22,7 @@ fn run_function_with_args(meta: &mut ParserMetadata, name: &str, args: &[Type])
if let Ok(()) = syntax(&mut new_meta, &mut block) {
// Pop function body
new_meta.mem.pop_scope();
new_meta.function_ctx = function_ctx;
// Persist the new function instance
meta.mem.add_function_instance(function.id, args, Type::Text, block)
} else { 0 }
Expand Down
13 changes: 10 additions & 3 deletions src/modules/variable/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use super::{variable_name_extensions, handle_identifier_name};
#[derive(Debug, Clone)]
pub struct VariableInit {
name: String,
expr: Box<Expr>
expr: Box<Expr>,
function_ctx: bool
}

impl VariableInit {
Expand All @@ -26,7 +27,8 @@ impl SyntaxModule<ParserMetadata> for VariableInit {
fn new() -> Self {
VariableInit {
name: String::new(),
expr: Box::new(Expr::new())
expr: Box::new(Expr::new()),
function_ctx: false
}
}

Expand All @@ -35,6 +37,7 @@ impl SyntaxModule<ParserMetadata> for VariableInit {
// Get the variable name
let tok = meta.get_current_token();
self.name = variable(meta, variable_name_extensions())?;
self.function_ctx = meta.function_ctx;
context!({
token(meta, "=")?;
syntax(meta, &mut *self.expr)?;
Expand All @@ -56,6 +59,10 @@ impl TranslateModule for VariableInit {
fn translate(&self, meta: &mut TranslateMetadata) -> String {
let name = self.name.clone();
let expr = self.expr.translate(meta);
format!("{name}={expr}")
if self.function_ctx {
format!("local {name}={expr}")
} else {
format!("{name}={expr}")
}
}
}
6 changes: 4 additions & 2 deletions src/utils/metadata/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ pub struct ParserMetadata {
pub binop_border: Option<usize>,
pub mem: Memory,
debug: Option<usize>,
pub loop_ctx: bool
pub loop_ctx: bool,
pub function_ctx: bool
}

impl Metadata for ParserMetadata {
Expand All @@ -23,7 +24,8 @@ impl Metadata for ParserMetadata {
binop_border: None,
mem: Memory::new(),
debug: None,
loop_ctx: false
loop_ctx: false,
function_ctx: false
}
}

Expand Down