undefalias

This commit is contained in:
2021-07-22 16:32:33 -06:00
parent e52ed1abd1
commit b54073fa32
4 changed files with 39 additions and 7 deletions

View File

@@ -497,10 +497,13 @@ class Macros {
return null;
};
macros["defalias"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
wholeExp.checkNumArgs(2, 2, "(defalias [[&call or &ident] whenItsThis] [makeItThis])");
var aliasMap:Map<String, ReaderExpDef> = null;
var nameExp = switch (exps[0].def) {
// Having this floating out here is sketchy, but should work out fine because the variable is always re-set
// through the next function before being used in defalias or undefalias
var aliasMap:Map<String, ReaderExpDef> = null;
function getAliasName(k:KissState, nameExpWithMeta:ReaderExp, formName:String):String {
var error = CompileError.fromExp(nameExpWithMeta, 'first argument to $formName should be &call [alias] or &ident [alias]');
var nameExp = switch (nameExpWithMeta.def) {
case MetaExp("call", nameExp):
aliasMap = k.callAliases;
nameExp;
@@ -508,18 +511,32 @@ class Macros {
aliasMap = k.identAliases;
nameExp;
default:
throw CompileError.fromExp(exps[0], 'first argument to defalias should be a symbol for the alias annotated with either &call or &ident');
throw error;
};
var name = switch (nameExp.def) {
return switch (nameExp.def) {
case Symbol(whenItsThis):
whenItsThis;
default:
throw CompileError.fromExp(exps[0], 'first argument to defalias should be a symbol for the alias annotated with either &call or &ident');
throw error;
};
}
macros["defalias"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
wholeExp.checkNumArgs(2, 2, "(defalias [[&call or &ident] whenItsThis] [makeItThis])");
var name = getAliasName(k, exps[0], "defalias");
aliasMap[name] = exps[1].def;
return null;
};
macros["undefalias"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
wholeExp.checkNumArgs(1, 1, "(undefalias [[&call or &ident] alias])");
var name = getAliasName(k, exps[0], "undefalias");
aliasMap.remove(name);
return null;
};
// Macros that null-check and extract patterns from enums (inspired by Rust)
function ifLet(wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) {
wholeExp.checkNumArgs(2, 3, "(ifLet [[enum bindings...]] [thenExp] [?elseExp])");

View File

@@ -23,6 +23,7 @@
(Assert.equals 4 b))
(otherwise
(Assert.fail)))
(case l
([::...rest last]
(Assert.equals (.toString [1 2 3]) (.toString rest))

View File

@@ -23,4 +23,9 @@ class MacroTestCase extends Test {
function testModularMacros() {
Assert.equals("Nat 5", nameAndNumber("Nat", 5));
}
function testUndefAlias() {
Assert.equals(9, print);
Assert.equals(9, aliasValue());
}
}

View File

@@ -35,3 +35,12 @@
(altDefun nameAndNumber [name String number Int]
"$name $number")
// If for whatever reason, you wanted to make a variable called print
(undefalias &call print)
(defvar print 9)
(defalias &ident alias 5)
(undefalias &ident alias)
(defvar alias 9)
(defun aliasValue [] alias)