change more complicated doc() cases. Close #30
This commit is contained in:
@@ -214,31 +214,34 @@ class Macros {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bodyIf(formName:String, underlyingIf:String, negated:Bool, wholeExp:ReaderExp, args:Array<ReaderExp>, k) {
|
function addBodyIf(keywordName:String, underlyingIf:String, negated:Bool) {
|
||||||
wholeExp.checkNumArgs(2, null, '($formName [condition] [body...])');
|
k.doc(keywordName, 2, null, '($keywordName <condition> <body...>)');
|
||||||
var b = wholeExp.expBuilder();
|
macros[keywordName] = (wholeExp:ReaderExp, args:Array<ReaderExp>, k) -> {
|
||||||
var condition = if (negated) {
|
var b = wholeExp.expBuilder();
|
||||||
b.call(
|
var condition = if (negated) {
|
||||||
b.symbol("not"), [
|
b.call(
|
||||||
args[0]
|
b.symbol("not"), [
|
||||||
]);
|
args[0]
|
||||||
} else {
|
]);
|
||||||
args[0];
|
} else {
|
||||||
}
|
args[0];
|
||||||
return b.call(b.symbol(underlyingIf), [
|
}
|
||||||
condition,
|
return b.call(b.symbol(underlyingIf), [
|
||||||
b.begin(args.slice(1))
|
condition,
|
||||||
]);
|
b.begin(args.slice(1))
|
||||||
|
]);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
macros["when"] = bodyIf.bind("when", "if", false);
|
addBodyIf("when", "if", false);
|
||||||
macros["unless"] = bodyIf.bind("unless", "if", true);
|
addBodyIf("unless", "if", true);
|
||||||
macros["#when"] = bodyIf.bind("#when", "#if", false);
|
addBodyIf("#when", "#if", false);
|
||||||
macros["#unless"] = bodyIf.bind("#unless", "#if", true);
|
addBodyIf("#unless", "#if", true);
|
||||||
macros["cond"] = cond.bind("cond", "if");
|
|
||||||
macros["#cond"] = cond.bind("#cond", "#if");
|
addCond(k, macros, "cond", "if");
|
||||||
|
addCond(k, macros, "#cond", "#if");
|
||||||
|
|
||||||
|
k.doc("or", 1, null, "(or <v1> <values...>)");
|
||||||
function _or(wholeExp:ReaderExp, args:Array<ReaderExp>, k) {
|
function _or(wholeExp:ReaderExp, args:Array<ReaderExp>, k) {
|
||||||
wholeExp.checkNumArgs(1, null, "(or <v1> <values...>)");
|
|
||||||
var b = wholeExp.expBuilder();
|
var b = wholeExp.expBuilder();
|
||||||
|
|
||||||
var uniqueVarSymbol = b.symbol();
|
var uniqueVarSymbol = b.symbol();
|
||||||
@@ -400,9 +403,9 @@ class Macros {
|
|||||||
argNames.push(name);
|
argNames.push(name);
|
||||||
if (optIndex == -1) {
|
if (optIndex == -1) {
|
||||||
++minArgs;
|
++minArgs;
|
||||||
macroCallForm += ' [$name]';
|
macroCallForm += ' <$name>';
|
||||||
} else {
|
} else {
|
||||||
macroCallForm += ' [?$name]';
|
macroCallForm += ' <?$name>';
|
||||||
}
|
}
|
||||||
++maxArgs;
|
++maxArgs;
|
||||||
case MetaExp("builder", {pos: _, def: Symbol(name)}):
|
case MetaExp("builder", {pos: _, def: Symbol(name)}):
|
||||||
@@ -413,7 +416,7 @@ class Macros {
|
|||||||
}
|
}
|
||||||
case MetaExp("opt", {pos: _, def: Symbol(name)}):
|
case MetaExp("opt", {pos: _, def: Symbol(name)}):
|
||||||
argNames.push(name);
|
argNames.push(name);
|
||||||
macroCallForm += ' [?$name]';
|
macroCallForm += ' <?$name>';
|
||||||
optIndex = maxArgs;
|
optIndex = maxArgs;
|
||||||
++maxArgs;
|
++maxArgs;
|
||||||
case MetaExp("rest", {pos: _, def: Symbol(name)}):
|
case MetaExp("rest", {pos: _, def: Symbol(name)}):
|
||||||
@@ -421,12 +424,12 @@ class Macros {
|
|||||||
KissError.warnFromExp(arg, "Consider using &body instead of &rest when writing macros with bodies.");
|
KissError.warnFromExp(arg, "Consider using &body instead of &rest when writing macros with bodies.");
|
||||||
}
|
}
|
||||||
argNames.push(name);
|
argNames.push(name);
|
||||||
macroCallForm += ' [$name...]';
|
macroCallForm += ' <$name...>';
|
||||||
restIndex = maxArgs;
|
restIndex = maxArgs;
|
||||||
maxArgs = null;
|
maxArgs = null;
|
||||||
case MetaExp("body", {pos: _, def: Symbol(name)}):
|
case MetaExp("body", {pos: _, def: Symbol(name)}):
|
||||||
argNames.push(name);
|
argNames.push(name);
|
||||||
macroCallForm += ' [$name...]';
|
macroCallForm += ' <$name...>';
|
||||||
restIndex = maxArgs;
|
restIndex = maxArgs;
|
||||||
requireRest = true;
|
requireRest = true;
|
||||||
maxArgs = null;
|
maxArgs = null;
|
||||||
@@ -441,8 +444,8 @@ class Macros {
|
|||||||
if (restIndex == -1)
|
if (restIndex == -1)
|
||||||
restIndex = optIndex;
|
restIndex = optIndex;
|
||||||
|
|
||||||
|
k.doc(name, minArgs, maxArgs, macroCallForm);
|
||||||
macros[name] = (wholeExp:ReaderExp, innerExps:Array<ReaderExp>, k:KissState) -> {
|
macros[name] = (wholeExp:ReaderExp, innerExps:Array<ReaderExp>, k:KissState) -> {
|
||||||
wholeExp.checkNumArgs(minArgs, maxArgs, macroCallForm);
|
|
||||||
var b = wholeExp.expBuilder();
|
var b = wholeExp.expBuilder();
|
||||||
var innerArgNames = argNames.copy();
|
var innerArgNames = argNames.copy();
|
||||||
|
|
||||||
@@ -1270,23 +1273,25 @@ class Macros {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cond expands telescopically into a nested if expression
|
// cond expands telescopically into a nested if expression
|
||||||
|
static function addCond(k:KissState, macros:Map<String,MacroFunction>, formName:String, underlyingIf:String) {
|
||||||
static function cond(formName:String, underlyingIf:String, wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) {
|
k.doc(formName, 1, null, '($formName (<condition> <body...>) <more cases...>)');
|
||||||
wholeExp.checkNumArgs(1, null, '($formName [cases...])');
|
function cond (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) {
|
||||||
var b = wholeExp.expBuilder();
|
var b = wholeExp.expBuilder();
|
||||||
return switch (exps[0].def) {
|
return switch (exps[0].def) {
|
||||||
case CallExp(condition, body):
|
case CallExp(condition, body):
|
||||||
b.call(b.symbol(underlyingIf), [
|
b.call(b.symbol(underlyingIf), [
|
||||||
condition,
|
condition,
|
||||||
b.begin(body),
|
b.begin(body),
|
||||||
if (exps.length > 1) {
|
if (exps.length > 1) {
|
||||||
cond(formName, underlyingIf, b.callSymbol(formName, exps.slice(1)), exps.slice(1), k);
|
cond(b.callSymbol(formName, exps.slice(1)), exps.slice(1), k);
|
||||||
} else {
|
} else {
|
||||||
b.symbol("null");
|
b.symbol("null");
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
default:
|
default:
|
||||||
throw KissError.fromExp(exps[0], 'top-level expression of (cond... ) must be a call list starting with a condition expression');
|
throw KissError.fromExp(exps[0], 'top-level expression of ($formName... ) must be a call list starting with a condition expression');
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
macros[formName] = cond;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -473,7 +473,7 @@ class SpecialForms {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static function caseOr(wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState):Expr {
|
public static function caseOr(wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState):Expr {
|
||||||
wholeExp.checkNumArgs(2, null, "(or <v1> <v2> <values...>)");
|
wholeExp.checkNumArgs(2, null, "(or <pattern1> <pattern2> <patterns...>)");
|
||||||
return if (args.length == 2) {
|
return if (args.length == 2) {
|
||||||
macro ${k.convert(args[0])} | ${k.convert(args[1])};
|
macro ${k.convert(args[0])} | ${k.convert(args[1])};
|
||||||
} else {
|
} else {
|
||||||
@@ -482,7 +482,7 @@ class SpecialForms {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public static function caseAs(wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState):Expr {
|
public static function caseAs(wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState):Expr {
|
||||||
wholeExp.checkNumArgs(2, 2, "(as [name] [pattern])");
|
wholeExp.checkNumArgs(2, 2, "(as <name> <pattern>)");
|
||||||
return macro ${k.convert(args[0])} = ${k.convert(args[1])};
|
return macro ${k.convert(args[0])} = ${k.convert(args[1])};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user