add native function `ceil`

This commit is contained in:
ValKmjolnir 2023-10-26 00:04:20 +08:00
parent d56e1bff2c
commit bbed29eb65
4 changed files with 59 additions and 33 deletions

View File

@ -157,6 +157,11 @@ var builtin_floor(context* ctx, gc* ngc) {
return var::num(std::floor(value.num())); return var::num(std::floor(value.num()));
} }
var builtin_ceil(context* ctx, gc* ngc) {
auto value = ctx->localr[1];
return var::num(std::ceil(value.num()));
}
var builtin_num(context* ctx, gc* ngc) { var builtin_num(context* ctx, gc* ngc) {
auto val = ctx->localr[1]; auto val = ctx->localr[1];
if (val.type==vm_num) { if (val.type==vm_num) {
@ -653,6 +658,7 @@ nasal_builtin_table builtin[] = {
{"__id", builtin_id}, {"__id", builtin_id},
{"__int", builtin_int}, {"__int", builtin_int},
{"__floor", builtin_floor}, {"__floor", builtin_floor},
{"__ceil", builtin_ceil},
{"__num", builtin_num}, {"__num", builtin_num},
{"__pop", builtin_pop}, {"__pop", builtin_pop},
{"__str", builtin_str}, {"__str", builtin_str},

View File

@ -42,6 +42,7 @@ var builtin_rand(context*, gc*);
var builtin_id(context*, gc*); var builtin_id(context*, gc*);
var builtin_int(context*, gc*); var builtin_int(context*, gc*);
var builtin_floor(context*, gc*); var builtin_floor(context*, gc*);
var builtin_ceil(context*, gc*);
var builtin_num(context*, gc*); var builtin_num(context*, gc*);
var builtin_pop(context*, gc*); var builtin_pop(context*, gc*);
var builtin_str(context*, gc*); var builtin_str(context*, gc*);

View File

@ -2,8 +2,16 @@
# 2021 ValKmjolnir # 2021 ValKmjolnir
var ( var (
_j_eof, _j_lbrace, _j_rbrace, _j_lbrkt, _j_rbrkt, _j_eof,
_j_comma, _j_colon, _j_str, _j_num, _j_id _j_lbrace,
_j_rbrace,
_j_lbrkt,
_j_rbrkt,
_j_comma,
_j_colon,
_j_str,
_j_num,
_j_id
) = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9); ) = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
var _j_content = [ var _j_content = [
@ -146,28 +154,29 @@ var parse = func() {
} }
var match = func(type) { var match = func(type) {
if(token.type!=type) if(token.type!=type) {
println("json::parse: line ",line,": expect ",_j_content[type]," but get `",token.content,"`."); println("json::parse: line ",line,": expect ",_j_content[type]," but get `",token.content,"`.");
}
next(); next();
return; return;
} }
var member = func(hash) { var member = func(hash) {
var name = token.content; var name = token.content;
if(token.type==_j_rbrace) { if (token.type==_j_rbrace) {
return; return;
} }
if(token.type==_j_str) { if (token.type==_j_str) {
match(_j_str); match(_j_str);
} else { } else {
match(_j_id); match(_j_id);
} }
match(_j_colon); match(_j_colon);
if(token.type==_j_lbrace) { if (token.type==_j_lbrace) {
hash[name] = hash_gen(); hash[name] = hash_gen();
} elsif(token.type==_j_lbrkt) { } elsif (token.type==_j_lbrkt) {
hash[name] = vec_gen(); hash[name] = vec_gen();
} elsif(token.type==_j_str or token.type==_j_num) { } elsif (token.type==_j_str or token.type==_j_num) {
hash[name] = token.content; hash[name] = token.content;
next(); next();
} }
@ -189,21 +198,21 @@ var parse = func() {
var vec_gen = func() { var vec_gen = func() {
var vec = []; var vec = [];
match(_j_lbrkt); match(_j_lbrkt);
if(token.type==_j_lbrace) { if (token.type==_j_lbrace) {
append(vec, hash_gen()); append(vec, hash_gen());
} elsif(token.type==_j_lbrkt) { } elsif (token.type==_j_lbrkt) {
append(vec, vec_gen()); append(vec, vec_gen());
} elsif(token.type==_j_str or token.type==_j_num) { } elsif (token.type==_j_str or token.type==_j_num) {
append(vec, token.content); append(vec, token.content);
next(); next();
} }
while(token.type==_j_comma) { while(token.type==_j_comma) {
match(_j_comma); match(_j_comma);
if(token.type==_j_lbrace) { if (token.type==_j_lbrace) {
append(vec, hash_gen()); append(vec, hash_gen());
} elsif(token.type==_j_lbrkt) { } elsif (token.type==_j_lbrkt) {
append(vec, vec_gen()); append(vec, vec_gen());
} elsif(token.type==_j_str or token.type==_j_num) { } elsif (token.type==_j_str or token.type==_j_num) {
append(vec, token.content); append(vec, token.content);
next(); next();
} }
@ -242,13 +251,13 @@ var stringify = func(object) {
var s = ""; var s = "";
var gen = func(elem) { var gen = func(elem) {
var t = typeof(elem); var t = typeof(elem);
if(t=="num") { if (t=="num") {
s ~= str(elem); s ~= str(elem);
} elsif(t=="str") { } elsif (t=="str") {
s ~= '"'~elem~'"'; s ~= '"'~elem~'"';
} elsif(t=="vec") { } elsif (t=="vec") {
vgen(elem); vgen(elem);
} elsif(t=="hash") { } elsif (t=="hash") {
hgen(elem); hgen(elem);
} else { } else {
s ~= '"undefined"'; s ~= '"undefined"';

View File

@ -75,6 +75,10 @@ var floor = func(val) {
return __floor(val); return __floor(val);
} }
var ceil = func(val) {
return __ceil(val);
}
# exit using std::exit # exit using std::exit
var exit = func(val = -1) { var exit = func(val = -1) {
return __exit(val); return __exit(val);
@ -228,19 +232,21 @@ var println = func(elems...) {
# sort function using quick sort # sort function using quick sort
# not very efficient... :( # not very efficient... :(
var sort = func(){ var sort = func() {
srand(); # be aware! this causes global changes srand(); # be aware! this causes global changes
var quick_sort_core = func(vec, left, right, cmp) { var quick_sort_core = func(vec, left, right, cmp) {
if(left>=right) return nil; if(left>=right) return nil;
var base = left+int(rand()*(right-left)); var base = left+int(rand()*(right-left));
(vec[left], vec[base]) = (vec[base], vec[left]); (vec[left], vec[base]) = (vec[base], vec[left]);
var (i, j, tmp) = (left, right, vec[left]); var (i, j, tmp) = (left, right, vec[left]);
while(i<j){ while(i<j) {
while(i<j and cmp(tmp,vec[j])) while(i<j and cmp(tmp,vec[j])) {
j -= 1; j -= 1;
}
vec[i] = vec[j]; vec[i] = vec[j];
while(i<j and cmp(vec[i],tmp)) while(i<j and cmp(vec[i],tmp)) {
i += 1; i += 1;
}
vec[j] = vec[i]; vec[j] = vec[i];
j -= 1; j -= 1;
} }
@ -249,7 +255,7 @@ var sort = func(){
quick_sort_core(vec, i+1, right, cmp); quick_sort_core(vec, i+1, right, cmp);
return nil; return nil;
} }
return func(vec, cmp = func(a, b) {return a<b;}){ return func(vec, cmp = func(a, b) {return a<b;}) {
quick_sort_core(vec, 0, size(vec)-1, cmp); quick_sort_core(vec, 0, size(vec)-1, cmp);
return nil; return nil;
} }
@ -276,7 +282,7 @@ var isnum = func(x) {
} }
var isscalar = func(s) { var isscalar = func(s) {
var t=typeof(s); var t = typeof(s);
return (t=="num" or t=="str")? 1:0; return (t=="num" or t=="str")? 1:0;
} }
@ -293,25 +299,29 @@ var ghosttype = func(ghost_object) {
} }
# get the index of val in the vec # get the index of val in the vec
var vecindex = func(vec,val) { var vecindex = func(vec, val) {
forindex(var i;vec) forindex(var i; vec) {
if(val==vec[i]) if(val==vec[i]) {
return i; return i;
}
}
return nil; return nil;
} }
# check if the object is an instance of the class # check if the object is an instance of the class
var isa = func(object, class) { var isa = func(object, class) {
if (!ishash(object)) { if (!ishash(object)) {
return 0; return false;
} }
if(!contains(object, "parents") or !isvec(object.parents)) { if(!contains(object, "parents") or !isvec(object.parents)) {
return 0; return false;
} }
foreach(var elem;object.parents) foreach(var elem; object.parents) {
if(elem==class or isa(elem, class)) if(elem==class or isa(elem, class)) {
return 1; return true;
return 0; }
}
return false;
} }
# assert aborts when condition is not true # assert aborts when condition is not true