Skip to content

Commit

Permalink
[update built-in class] update Range class and it's method.
Browse files Browse the repository at this point in the history
  • Loading branch information
asxez committed Apr 6, 2024
1 parent 9bffb66 commit 09fe14a
Showing 1 changed file with 74 additions and 0 deletions.
74 changes: 74 additions & 0 deletions vm/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,71 @@ static bool primMapValueIteratorValue(VM *vm, Value *args) {
RET_VALUE(entry->value)
}

//objRange.from:返回range的from
static bool primRangeFrom(VM *vm UNUSED, Value *args) {
RET_NUM(VALUE_TO_OBJRANGE(args[0])->from)
}

//objRange.to:返回range的to
static bool primRangeTo(VM *vm UNUSED, Value *args) {
RET_NUM(VALUE_TO_OBJRANGE(args[0])->to)
}

//objRange.min:返回range中from和to较小的值
static bool primRangeMin(VM *vm UNUSED, Value *args) {
ObjRange *objRange = VALUE_TO_OBJRANGE(args[0]);
RET_NUM(fmin(objRange->from, objRange->to))
}

//objRange.max:返回range中from和to较大的值
static bool primRangeMax(VM *vm UNUSED, Value *args) {
ObjRange *objRange = VALUE_TO_OBJRANGE(args[0]);
RET_NUM(fmax(objRange->from, objRange->to))
}

//objRange.iterate(_):迭代range中的值,并不索引
static bool primRangeIterate(VM *vm, Value *args) {
ObjRange *objRange = VALUE_TO_OBJRANGE(args[0]);

//若未提供iter说明是第一次迭代,因此返回range->from
if (VALUE_IS_NULL(args[1]))
RET_NUM(objRange->from)

//迭代器必须是数字
if (!validateNum(vm, args[1]))
return false;
double iter = VALUE_TO_NUM(args[1]);

//若是正方向
if (objRange->from < objRange->to) {
iter++;
if (iter > objRange->to)
RET_FALSE
} else { //若是反向迭代
iter--;
if (iter < objRange->to)
RET_FALSE
}
RET_NUM(iter)
}

//objRange.iteratorValue(_):range的迭代就是range中从from到to之间的值,因此直接返回迭代器就是range的值
static bool primRangeIteratorValue(VM *vm UNUSED, Value *args) {
ObjRange *objRange = VALUE_TO_OBJRANGE(args[0]);
double value = VALUE_TO_NUM(args[1]);

//确保args[1]在from到to的范围中
//若是正方向
if (objRange->from < objRange->to) {
if (value >= objRange->from && value <= objRange->to)
RET_VALUE(args[1])
} else { //若是负方向
if (value <= objRange->from && value >= objRange->to)
RET_VALUE(args[1])
}
RET_FALSE
}

//从modules中获取名为moduleName的模块
static ObjModule *getModule(VM *vm, Value moduleName) {
Value value = mapGet(vm->allModules, moduleName);
Expand Down Expand Up @@ -1507,4 +1572,13 @@ void buildCore(VM *vm) {
PRIM_METHOD_BIND(vm->mapClass, "iterate_(_)", primMapIterate)
PRIM_METHOD_BIND(vm->mapClass, "keyIteratorValue_(_)", primMapKeyIteratorValue)
PRIM_METHOD_BIND(vm->mapClass, "valueIteratorValue_(_)", primMapValueIteratorValue)

//绑定Range类
vm->rangeClass = VALUE_TO_CLASS(getCoreClassValue(coreModule, "Range"));
PRIM_METHOD_BIND(vm->rangeClass, "from", primRangeFrom)
PRIM_METHOD_BIND(vm->rangeClass, "to", primRangeTo)
PRIM_METHOD_BIND(vm->rangeClass, "min", primRangeMin)
PRIM_METHOD_BIND(vm->rangeClass, "max", primRangeMax)
PRIM_METHOD_BIND(vm->rangeClass, "iterate(_)", primRangeIterate)
PRIM_METHOD_BIND(vm->rangeClass, "iteratorValue(_)", primRangeIteratorValue)
}

0 comments on commit 09fe14a

Please sign in to comment.