Skip to content

Commit

Permalink
Merge pull request #95 from oneplus1000/master
Browse files Browse the repository at this point in the history
Add method in DateTime and Duration
  • Loading branch information
ethanblake4 authored Oct 1, 2023
2 parents f95a589 + 8443fc0 commit ed1db7f
Show file tree
Hide file tree
Showing 12 changed files with 607 additions and 8 deletions.
7 changes: 6 additions & 1 deletion lib/src/eval/compiler/builtins.dart
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ final Map<TypeRef, Map<String, KnownMethod>> knownMethods = {
'<=': numComparisonOp,
'>=': numComparisonOp,
'==': numComparisonOp,
'!=': numComparisonOp,
..._knownObject
},
EvalTypes.doubleType: {
Expand All @@ -192,6 +193,7 @@ final Map<TypeRef, Map<String, KnownMethod>> knownMethods = {
'<=': numComparisonOp,
'>=': numComparisonOp,
'==': numComparisonOp,
'!=': numComparisonOp,
..._knownObject
},
EvalTypes.numType: {
Expand All @@ -205,14 +207,17 @@ final Map<TypeRef, Map<String, KnownMethod>> knownMethods = {
'<=': numComparisonOp,
'>=': numComparisonOp,
'==': numComparisonOp,
'!=': numComparisonOp,
..._knownObject
},
EvalTypes.boolType: {'&&': boolBinaryOp, '||': boolBinaryOp},
EvalTypes.boolType: {'&&': boolBinaryOp, '||': boolBinaryOp, '==': boolBinaryOp, '!=': boolBinaryOp},
EvalTypes.stringType: {
'+': KnownMethod(
AlwaysReturnType(EvalTypes.stringType, false), [KnownMethodArg('other', EvalTypes.stringType, false)], {}),
'==': KnownMethod(
AlwaysReturnType(EvalTypes.boolType, false), [KnownMethodArg('other', EvalTypes.stringType, false)], {}),
'!=': KnownMethod(
AlwaysReturnType(EvalTypes.boolType, false), [KnownMethodArg('other', EvalTypes.stringType, false)], {}),
'codeUnitAt': KnownMethod(
AlwaysReturnType(EvalTypes.intType, false), [KnownMethodArg('index', EvalTypes.intType, false)], {}),
'compareTo': KnownMethod(
Expand Down
1 change: 1 addition & 0 deletions lib/src/eval/compiler/context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ class CompilerContext with ScopeContext {

@override
int pushOp(EvcOp op, int length) {
//print('#: ${op.toString()}');
out.add(op);
position += length;
return out.length - 1;
Expand Down
3 changes: 2 additions & 1 deletion lib/src/eval/compiler/expression/binary.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ Variable compileBinaryExpression(CompilerContext ctx, BinaryExpression e, [TypeR
TokenType.PERCENT: '%',
TokenType.EQ_EQ: '==',
TokenType.AMPERSAND_AMPERSAND: '&&',
TokenType.BAR_BAR: '||'
TokenType.BAR_BAR: '||',
TokenType.BANG_EQ: '!='
};

var method = opMap[e.operator.type] ?? (throw CompileError('Unknown binary operator ${e.operator.type}'));
Expand Down
10 changes: 8 additions & 2 deletions lib/src/eval/compiler/expression/prefix.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ Variable compilePrefixExpression(CompilerContext ctx, PrefixExpression e) {

final opMap = {
TokenType.MINUS: '-',
TokenType.BANG: '!',
};

var method = opMap[e.operator.type] ?? (throw CompileError('Unknown unary operator ${e.operator.type}'));

if (V.type != EvalTypes.intType && V.type != EvalTypes.doubleType) {
throw CompileError('Unary operator $method is currently only supported for ints and doubles');
if (V.type != EvalTypes.intType && V.type != EvalTypes.doubleType && V.type != EvalTypes.boolType) {
throw CompileError('Unary operator $method is currently only supported for bool , ints and doubles');
}

if (V.type == EvalTypes.boolType) {
final boolVal = BuiltinValue(boolval: false);
return boolVal.push(ctx).invoke(ctx, method, [V]).result;
}
final zero = V.type == EvalTypes.intType ? BuiltinValue(intval: 0) : BuiltinValue(doubleval: 0.0);
return zero.push(ctx).invoke(ctx, method, [V]).result;
Expand Down
1 change: 0 additions & 1 deletion lib/src/eval/compiler/macros/branch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ StatementInfo macroBranch(CompilerContext ctx, AlwaysReturnType? expectedReturnT
required MacroStatementClosure thenBranch,
MacroStatementClosure? elseBranch}) {
ctx.beginAllocScope();

final conditionResult = condition(ctx).unboxIfNeeded(ctx);

final rewriteCond = JumpIfFalse.make(conditionResult.scopeFrameOffset, -1);
Expand Down
20 changes: 19 additions & 1 deletion lib/src/eval/compiler/variable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ class Variable {
var $this = this;

final supportedNumIntrinsicOps = {'+', '-', '<', '>', '<=', '>='};
final supportedBoolIntrinsicOps = {'!'};
if (type.isAssignableTo(ctx, EvalTypes.numType, forceAllowDynamic: false) &&
supportedNumIntrinsicOps.contains(method)) {
$this = unboxIfNeeded(ctx);
Expand Down Expand Up @@ -198,15 +199,31 @@ class Variable {
throw CompileError('Unknown num intrinsic method "$method"');
}

return InvokeResult($this, result, [R]);
} else if (type.isAssignableTo(ctx, EvalTypes.boolType, forceAllowDynamic: false) &&
supportedBoolIntrinsicOps.contains(method)) {
var R = args[0];
if (R.scopeFrameOffset == scopeFrameOffset) {
R = $this;
} else {
R = R.unboxIfNeeded(ctx);
}
//ctx.pushOp(
// NumSub.make($this.scopeFrameOffset, R.scopeFrameOffset), NumSub.LEN);
ctx.pushOp(LogicalNot.make(R.scopeFrameOffset), LogicalNot.LEN);
var result = Variable.alloc(ctx, TypeRef.commonBaseType(ctx, {$this.type, R.type}).copyWith(boxed: false));
return InvokeResult($this, result, [R]);
}

final _boxed = boxUnboxMultiple(ctx, [$this, ...args], true);
$this = _boxed[0];
final _args = _boxed.sublist(1);
final checkEq = method == '==' && _args.length == 1;
final checkNotEq = method == '!=' && _args.length == 1;
if (checkEq) {
ctx.pushOp(CheckEq.make($this.scopeFrameOffset, _args[0].scopeFrameOffset), CheckEq.LEN);
} else if (checkNotEq) {
ctx.pushOp(CheckNotEq.make($this.scopeFrameOffset, _args[0].scopeFrameOffset), CheckNotEq.LEN);
} else {
for (final _arg in _args) {
ctx.pushOp(PushArg.make(_arg.scopeFrameOffset), PushArg.LEN);
Expand All @@ -226,7 +243,8 @@ class Variable {
AlwaysReturnType.fromInstanceMethodOrBuiltin(ctx, $this.type, method, [..._args.map((e) => e.type)], {});
}

final v = Variable.alloc(ctx, (returnType?.type ?? EvalTypes.dynamicType).copyWith(boxed: !checkEq));
final v =
Variable.alloc(ctx, (returnType?.type ?? EvalTypes.dynamicType).copyWith(boxed: !(checkEq || checkNotEq)));
return InvokeResult($this, v, _args);
}

Expand Down
48 changes: 48 additions & 0 deletions lib/src/eval/runtime/ops/objects.dart
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,51 @@ class IsType implements EvcOp {
@override
String toString() => 'IsType (L$_objectOffset is${_not ? '!' : ''} $_type)';
}

class CheckNotEq implements EvcOp {
CheckNotEq(Runtime runtime)
: _value1 = runtime._readInt16(),
_value2 = runtime._readInt16();

CheckNotEq.make(this._value1, this._value2);

final int _value1;
final int _value2;

static const int LEN = Evc.BASE_OPLEN + Evc.I16_LEN * 2;

@override
void run(Runtime runtime) {
var v1 = runtime.frame[_value1];
final v2 = runtime.frame[_value2];

while (true) {
if (v1 is $InstanceImpl) {
final methods = v1.evalClass.methods;
final _offset = methods['!='];
if (_offset == null) {
v1 = v1.evalSuperclass;
continue;
}
runtime.args = [v2];
runtime.callStack.add(runtime._prOffset);
runtime.catchStack.add([]);
runtime._prOffset = _offset;
return;
}

if (v1 is $Instance) {
final method = v1.$getProperty(runtime, '!=') as EvalFunction;
runtime.returnValue = method.call(runtime, v1, [v2 == null ? null : v2 as $Value])!.$value;
runtime.args = [];
return;
}

runtime.returnValue = v1 != v2;
return;
}
}

@override
String toString() => 'CheckNotEq (L$_value1 == L$_value2)';
}
9 changes: 9 additions & 0 deletions lib/src/eval/shared/stdlib/core/base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class $Object implements $Instance {
switch (identifier) {
case '==':
return __equals;
case '!=':
return __not_equals;
case 'toString':
return __toString;
case 'hashCode':
Expand All @@ -55,6 +57,13 @@ class $Object implements $Instance {
return $bool(target!.$value == other!.$value);
}

static const $Function __not_equals = $Function(_not_equals);

static $Value? _not_equals(Runtime runtime, $Value? target, List<$Value?> args) {
final other = args[0];
return $bool(target!.$value != other!.$value);
}

static const $Function __toString = $Function(_toString);

static $Value? _toString(Runtime runtime, $Value? target, List<$Value?> args) {
Expand Down
Loading

0 comments on commit ed1db7f

Please sign in to comment.