Fix type annotation for &mut properties in defnew

This commit is contained in:
2021-05-03 15:24:50 -06:00
parent 584d4bf140
commit d3e28ff8fa
6 changed files with 39 additions and 44 deletions

View File

@@ -84,11 +84,7 @@ class FieldForms {
return { return {
name: name, name: name,
access: access, access: access,
kind: FVar(switch (args[0].def) { kind: FVar(Helpers.explicitType(args[0]), if (args.length > 1) k.convert(args[1]) else null),
case TypedExp(type, _):
Helpers.parseComplexType(type, args[0]);
default: null;
}, if (args.length > 1) k.convert(args[1]) else null),
pos: wholeExp.macroPos() pos: wholeExp.macroPos()
}; };
} }
@@ -103,7 +99,7 @@ class FieldForms {
return { return {
name: name, name: name,
access: access, access: access,
kind: FFun(Helpers.makeFunction(args[0], returnsValue, args[1], args.slice(2), k)), kind: FFun(Helpers.makeFunction(args[0], returnsValue, args[1], args.slice(2), k, formName)),
pos: wholeExp.macroPos() pos: wholeExp.macroPos()
}; };
} }

View File

@@ -59,33 +59,31 @@ class Helpers {
}; };
} }
public static function varName(formName:String, nameExp:ReaderExp) { public static function explicitType(nameExp:ReaderExp):ComplexType {
return switch (nameExp.def) {
case MetaExp(_, innerExp):
explicitType(innerExp);
case TypedExp(type, _):
Helpers.parseComplexType(type, nameExp);
default: null;
};
}
public static function varName(formName:String, nameExp:ReaderExp, nameType="variable") {
return switch (nameExp.def) { return switch (nameExp.def) {
case Symbol(name): case Symbol(name):
name; name;
case MetaExp(_, nameExp) | TypedExp(_, nameExp): case MetaExp(_, nameExp) | TypedExp(_, nameExp):
varName(formName, nameExp); varName(formName, nameExp);
default: default:
throw CompileError.fromExp(nameExp, 'The first argument to $formName should be a variable name, :Typed variable name, and/or &meta variable name.'); throw CompileError.fromExp(nameExp, 'The first argument to $formName should be a $nameType name, :Typed $nameType name, and/or &meta $nameType name.');
}; };
} }
// TODO generic type parameter declarations // TODO generic type parameter declarations
public static function makeFunction(?name:ReaderExp, returnsValue:Bool, argList:ReaderExp, body:List<ReaderExp>, k:KissState):Function { public static function makeFunction(?name:ReaderExp, returnsValue:Bool, argList:ReaderExp, body:List<ReaderExp>, k:KissState, formName:String):Function {
if (name != null) {
switch (name.def) {
case MetaExp(_, name):
return makeFunction(name, returnsValue, argList, body, k);
default:
}
}
var funcName = if (name != null) { var funcName = if (name != null) {
switch (name.def) { varName(formName, name, "function");
case Symbol(name) | TypedExp(_, {pos: _, def: Symbol(name)}):
name;
default:
throw CompileError.fromExp(name, 'function name should be a symbol or :Typed symbol');
};
} else { } else {
""; "";
}; };
@@ -129,6 +127,7 @@ class Helpers {
++numArgs; ++numArgs;
} }
{ {
// These could use varName() and explicitType() but so far there are no &meta annotations for function arguments
name: switch (funcArg.def) { name: switch (funcArg.def) {
case Symbol(name) | TypedExp(_, {pos: _, def: Symbol(name)}): case Symbol(name) | TypedExp(_, {pos: _, def: Symbol(name)}):
name; name;
@@ -152,13 +151,10 @@ class Helpers {
// To make function args immutable by default, we would use (let...) instead of (begin...) // To make function args immutable by default, we would use (let...) instead of (begin...)
// to make the body expression. // to make the body expression.
// But setting default arguments is so common, and arguments are not settable references, // But setting null arguments to default values is so common, and arguments are not settable references,
// so function args are not immutable. // so function args are not immutable.
return { return {
ret: if (name != null) switch (name.def) { ret: if (name != null) Helpers.explicitType(name) else null,
case TypedExp(type, _): Helpers.parseComplexType(type, name);
default: null;
} else null,
args: switch (argList.def) { args: switch (argList.def) {
case ListExp(funcArgs): case ListExp(funcArgs):
funcArgs.map(makeFuncArg); funcArgs.map(makeFuncArg);

View File

@@ -534,10 +534,16 @@ class Macros {
// TODO allow &prop in the arg list to bind it directly to a same-named variable // TODO allow &prop in the arg list to bind it directly to a same-named variable
var propertyDefs = [for (bindingPair in bindingPairs) {
var b = bindingPair[0].expBuilder();
b.call(b.symbol("defprop"), [bindingPair[0]]);
}];
var propertySetExps = [for (bindingPair in bindingPairs) {
var b = bindingPair[1].expBuilder();
b.call(b.symbol("set"), [b.symbol(Helpers.varName("a defprop property binding", bindingPair[0])), bindingPair[1]]);
}];
var b = wholeExp.expBuilder(); var b = wholeExp.expBuilder();
var propertyDefs = [for (bindingPair in bindingPairs) b.call(b.symbol("defprop"), [bindingPair[0]])];
var propertySetExps = [for (bindingPair in bindingPairs)
b.call(b.symbol("set"), [b.symbol(Helpers.varName("a defprop property binding", bindingPair[0])), bindingPair[1]])];
return b.begin(propertyDefs.concat([ return b.begin(propertyDefs.concat([
b.call(b.symbol("defmethod"), [ b.call(b.symbol("defmethod"), [
b.symbol("new"), b.symbol("new"),

View File

@@ -193,7 +193,7 @@ class SpecialForms {
default: default:
true; true;
} }
EFunction(FAnonymous, Helpers.makeFunction(null, returnsValue, args[0], args.slice(1), k)).withMacroPosOf(wholeExp); EFunction(FAnonymous, Helpers.makeFunction(null, returnsValue, args[0], args.slice(1), k, "lambda")).withMacroPosOf(wholeExp);
}; };
function forExpr(formName:String, wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState) { function forExpr(formName:String, wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState) {

View File

@@ -1,15 +1,14 @@
(defvar &inline :Float SPEED 140) (defvar &inline :Float SPEED 140)
(defprop &mut :EnemyType type null) (defnew [:Float x :Float y :EnemyType _type]
(defprop &mut :FSM brain null) [:EnemyType type _type
(defprop &mut :Float idleTimer null) :FSM brain (new FSM idle)
(defprop &mut :Float moveDirection null) &mut :Float idleTimer 0
(defprop &mut :Bool seesPlayer false) &mut :Float moveDirection -1
(defprop &mut :FlxPoint playerPosition null) &mut :Bool seesPlayer false
&mut :FlxPoint playerPosition (FlxPoint.get)]
(defmethod new [:Float x :Float y :EnemyType type]
(super x y) (super x y)
(set this.type type)
(loadGraphic (loadGraphic
(case type (case type
(BOSS (BOSS
@@ -28,10 +27,7 @@
(set width 8) (set width 8)
(set height 14) (set height 14)
(set offset.x 4) (set offset.x 4)
(set offset.y 2) (set offset.y 2))
(set brain (new FSM idle))
(set idleTimer 0)
(set playerPosition (FlxPoint.get)))
(defmethod &override :Void update [:Float elapsed] (defmethod &override :Void update [:Float elapsed]
(when (and (when (and

View File

@@ -10,6 +10,7 @@ import flixel.math.FlxPoint;
import flixel.math.FlxVelocity; import flixel.math.FlxVelocity;
import flixel.FlxObject; import flixel.FlxObject;
import flixel.addons.editors.ogmo.FlxOgmo3Loader; import flixel.addons.editors.ogmo.FlxOgmo3Loader;
import flixel.tile.FlxTilemap;
import flixel.group.FlxGroup; import flixel.group.FlxGroup;
import flixel.tweens.FlxTween; import flixel.tweens.FlxTween;
import flixel.tweens.FlxEase; import flixel.tweens.FlxEase;