Skip to content

Commit

Permalink
Symbol macros no longer clobber the function namespace (fixes #51)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mercerenies committed Sep 6, 2022
1 parent 78efc66 commit e53bb0a
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 9 deletions.
3 changes: 2 additions & 1 deletion src/compile/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use crate::gdscript::expr::{Expr, ExprF};
use crate::gdscript::stmt::Stmt;
use crate::gdscript::decl::{self, Decl, DeclF};
use crate::gdscript::inner_class;
use crate::gdscript::metadata;
use crate::sxp::reify::pretty::reify_pretty_expr;
use crate::runner::path::RPathBuf;

Expand Down Expand Up @@ -272,7 +273,7 @@ impl<'a, 'b, 'c, 'd, 'e> CompilerFrame<'a, 'b, 'c, 'd, 'e, CodeBuilder> {
// Note: Macros compile identically to functions, as far as
// this stage of compilation is concerned. They'll be resolved
// and then purged during the IR phase.
let gd_name = names::lisp_to_gd(name);
let gd_name = metadata::symbol_macro(&names::lisp_to_gd(name));
let function = factory::declare_function(self, gd_name, IRArgList::empty(), body, &stmt_wrapper::Return)?;
self.builder.add_decl(Decl::new(DeclF::FnDecl(decl::Static::IsStatic, function), decl.pos));
Ok(())
Expand Down
6 changes: 6 additions & 0 deletions src/gdscript/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ pub const CONS_META: &str = "__gdlisp_Primitive_Cons";
/// values in GDLisp.
pub const SYMBOL_META: &str = "__gdlisp_Primitive_Symbol";

/// Given a GDScript function name, prefix it appropriately for a
/// symbol macro with the given name.
pub fn symbol_macro(name: &str) -> String {
format!("{}_SymbolMacroFunction_{}", PREFIX, name)
}

/// Given a GDLisp lazy val, this is the name of the metadata with
/// suffix `name`.
///
Expand Down
10 changes: 9 additions & 1 deletion src/ir/incremental.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use crate::compile::names::generator::NameGenerator;
use crate::compile::frame::MAX_QUOTE_REIFY_DEPTH;
use crate::compile::body::class_initializer::InitTime;
use crate::gdscript::library;
use crate::gdscript::metadata;
use crate::gdscript::decl::Static;
use crate::pipeline::error::{PError, IOError};
use crate::pipeline::Pipeline;
Expand Down Expand Up @@ -838,11 +839,18 @@ impl IncCompiler {
let mut deps = Dependencies::identify(table.borrow(), &imported_names, &*Id::build(namespace, &tmp_name), pos);
deps.purge_unknowns(library::all_builtin_names(self.minimalist).iter().map(|x| x as &dyn IdLike<NS=Namespace>));

let runtime_name =
if namespace == Namespace::Value {
metadata::symbol_macro(&tmp_name)
} else {
tmp_name.clone()
};

// Aside from built-in functions, it must be the case that
// all referenced functions are already defined.
let names = deps.try_into_knowns()?;
let tmpfile = macros::create_macro_file(pipeline, self.imports.clone(), table.borrow(), names, pos, self.minimalist)?;
let m_id = pipeline.get_server_mut().stand_up_macro(tmp_name, decl.args, tmpfile).map_err(|err| IOError::new(err, pos))?;
let m_id = pipeline.get_server_mut().stand_up_macro(runtime_name, decl.args, tmpfile).map_err(|err| IOError::new(err, pos))?;
self.macros.insert(Id::new(namespace, orig_name), MacroData { id: m_id, imported: false });

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion tests/test/import_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ fn symbol_macro_uses_other_import_test() {
const _Import_0 = preload("res://example.gd")
static func x():
static func __gdlisp_SymbolMacroFunction_x():
return _Import_0.add_one(2)
Expand Down
4 changes: 2 additions & 2 deletions tests/test/lazy_val_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ static func _lazy_0():
return _cond
static func x():
static func __gdlisp_SymbolMacroFunction_x():
return GDLisp.cons(GDLisp.cons(GDLisp.intern("access-slot"), GDLisp.cons(GDLisp.cons(GDLisp.intern("contextual-load"), GDLisp.cons("res://TEST.gd", null)), GDLisp.cons(GDLisp.intern("_lazy_0"), null))), null)
"#);
}
Expand Down Expand Up @@ -52,7 +52,7 @@ static func _lazy_0():
return _cond
static func x():
static func __gdlisp_SymbolMacroFunction_x():
return GDLisp.cons(GDLisp.cons(GDLisp.intern("access-slot"), GDLisp.cons(GDLisp.cons(GDLisp.intern("contextual-load"), GDLisp.cons("res://TEST.gd", null)), GDLisp.cons(GDLisp.intern("_lazy_0"), null))), null)
"#);
}
Expand Down
24 changes: 21 additions & 3 deletions tests/test/macro_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub fn symbol_macro_test() {
assert_eq!(parse_compile_decl("((define-symbol-macro foo 10) (defn bar () foo))"), r#"extends Reference
static func foo():
static func __gdlisp_SymbolMacroFunction_foo():
return 10
Expand Down Expand Up @@ -304,6 +304,24 @@ static func run():
"#);
}

#[test]
pub fn symbol_macro_shared_name_with_function_test() {
assert_eq!(parse_and_run(r#"((define-symbol-macro foo 100)
(defn foo () 101)
(print foo)
(print (foo)))"#),
"\n100\n101\n");
}

#[test]
pub fn symbol_macro_shared_name_with_macro_test() {
assert_eq!(parse_and_run(r#"((define-symbol-macro foo 100)
(defmacro foo () 101)
(print foo)
(print (foo)))"#),
"\n100\n101\n");
}

#[test]
pub fn macrolet_global_function_shadowing_test_1() {
let result = parse_compile_decl("((defn foo () 100) (defn run () [(foo) (macrolet ((foo () 99)) (foo)) (foo)]))");
Expand Down Expand Up @@ -368,7 +386,7 @@ pub fn symbol_macrolet_global_function_shadowing_test_3() {
assert_eq!(result, r#"extends Reference
static func foo():
static func __gdlisp_SymbolMacroFunction_foo():
return 100
Expand All @@ -383,7 +401,7 @@ pub fn symbol_macrolet_global_function_shadowing_test_4() {
assert_eq!(result, r#"extends Reference
static func foo():
static func __gdlisp_SymbolMacroFunction_foo():
return 100
Expand Down
2 changes: 1 addition & 1 deletion tests/test/object_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static func _lazy_0():
return _cond
static func Foo():
static func __gdlisp_SymbolMacroFunction_Foo():
return GDLisp.cons(GDLisp.cons(GDLisp.intern("access-slot"), GDLisp.cons(GDLisp.cons(GDLisp.intern("contextual-load"), GDLisp.cons("res://TEST.gd", null)), GDLisp.cons(GDLisp.intern("_lazy_0"), null))), null)
"#);
}
Expand Down

0 comments on commit e53bb0a

Please sign in to comment.