967 lines
30 KiB
C
967 lines
30 KiB
C
#include "tlang.h"
|
|
#if defined(_WIN32) || defined(WIN32)
|
|
#include <conio.h>
|
|
#endif
|
|
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <math.h>
|
|
#include <unistd.h>
|
|
#if defined(USE_SDL2)
|
|
extern void runtime_register_sdl(runtime_t* rt);
|
|
#endif
|
|
#if defined(USE_THREADS)
|
|
extern void register_register_threads(runtime_t* rt,dict_t* create);
|
|
#endif
|
|
#if defined(USE_NETWORK)
|
|
extern void runtime_register_network(runtime_t* rt);
|
|
#endif
|
|
#if defined(USE_MBED)
|
|
extern void runtime_register_mbed(runtime_t* rt);
|
|
#endif
|
|
extern tobject_t* __ls_free(runtime_t* rt,void* ptr,list_tobject_t* ls);
|
|
extern tobject_t* __ls_get_current(runtime_t* rt,void* ptr,list_tobject_t* ls);
|
|
extern tobject_t* __ls_movenext(runtime_t* rt,void* ptr,list_tobject_t* ls);
|
|
extern tobject_t* __ls_reset(runtime_t* rt,void* ptr,list_tobject_t* ls);
|
|
void runtime_create_method_on_dict(dict_t* dict,char* name,runtime_t* rt,void* ptr,external_method_t cb,texternalmethod_free_t free)
|
|
{
|
|
kvp_t k;
|
|
k.key = name;
|
|
k.value = tobject_fromexternalmethod(rt,ptr,cb,free);
|
|
|
|
dict_setkvp(dict,k);
|
|
}
|
|
void runtime_create_number_on_dict(dict_t* dict,char* name,runtime_t* rt,double number)
|
|
{
|
|
kvp_t k;
|
|
k.key = name;
|
|
k.value = tobject_number(rt,number);
|
|
dict_setkvp(dict,k);
|
|
}
|
|
void runtime_create_bool_on_dict(dict_t* dict,char* name,runtime_t* rt,bool value)
|
|
{
|
|
kvp_t k;
|
|
k.key = name;
|
|
k.value = tobject_bool(rt,value);
|
|
dict_setkvp(dict,k);
|
|
}
|
|
void runtime_create_string_on_dict(dict_t* dict,char* name,runtime_t* rt,const char* value)
|
|
{
|
|
kvp_t k;
|
|
k.key = name;
|
|
k.value = tobject_stringp(rt,value);
|
|
dict_setkvp(dict,k);
|
|
}
|
|
void runtime_create_method_on_object(tobject_t* tdict_obj,char* name,runtime_t* rt,void* ptr,external_method_t cb,texternalmethod_free_t free)
|
|
{
|
|
runtime_create_method_on_dict(tdict_obj->data.dict,name,rt,ptr,cb,free);
|
|
}
|
|
void runtime_create_number_on_object(tobject_t* tdict_obj,char* name,runtime_t* rt,double number)
|
|
{
|
|
runtime_create_number_on_dict(tdict_obj->data.dict,name,rt,number);
|
|
}
|
|
void runtime_create_bool_on_object(tobject_t* tdict_obj,char* name,runtime_t* rt,bool value)
|
|
{
|
|
runtime_create_bool_on_dict(tdict_obj->data.dict,name,rt,value);
|
|
}
|
|
void runtime_create_string_on_object(tobject_t* tdict_obj,char* name,runtime_t* rt,const char* text)
|
|
{
|
|
runtime_create_string_on_dict(tdict_obj->data.dict,name,rt,text);
|
|
}
|
|
tobject_t* __console_clear_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
#if defined(_WIN32) || defined(WIN32)
|
|
clrscr();
|
|
#else
|
|
printf("\033[2J");
|
|
printf ("\x1b[%d;%dH", 0,0 );
|
|
#endif
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __fs_openreadwrite_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0 && args->items[0]->type == tstring)
|
|
{
|
|
stream_t* strm=stream_file_openreadwrite(args->items[0]->data.string);
|
|
if(strm != NULL)
|
|
{
|
|
return tobject_fromstream(rt,strm);
|
|
}
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __fs_append_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0 && args->items[0]->type == tstring)
|
|
{
|
|
stream_t* strm=stream_file_append(args->items[0]->data.string);
|
|
if(strm != NULL)
|
|
{
|
|
return tobject_fromstream(rt,strm);
|
|
}
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __fs_openread_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0 && args->items[0]->type == tstring)
|
|
{
|
|
stream_t* strm=stream_file_openread(args->items[0]->data.string);
|
|
if(strm != NULL)
|
|
{
|
|
return tobject_fromstream(rt,strm);
|
|
}
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __fs_readalltext_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0 && args->items[0]->type == tstring)
|
|
{
|
|
char* fileName = string_dupp(args->items[0]->data.string);
|
|
FILE* f = fopen(fileName,"r");
|
|
if(f)
|
|
{
|
|
string_t* str = string_create();
|
|
string_read(str,f,fread);
|
|
free(fileName);
|
|
fclose(f);
|
|
return tobject_string(rt,str);
|
|
}
|
|
free(fileName);
|
|
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __fs_parent_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0 && args->items[0]->type == tstring)
|
|
{
|
|
|
|
string_t* str=path_parent(args->items[0]->data.string);
|
|
return tobject_string(rt,str);
|
|
|
|
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __fs_get_filename_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0 && args->items[0]->type == tstring)
|
|
{
|
|
|
|
string_t* str=path_filename(args->items[0]->data.string);
|
|
return tobject_string(rt,str);
|
|
|
|
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __fs_get_extension_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0 && args->items[0]->type == tstring)
|
|
{
|
|
|
|
string_t* str=path_getextension(args->items[0]->data.string);
|
|
return tobject_string(rt,str);
|
|
|
|
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __fs_combine_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
string_t* path=NULL;
|
|
if(args->length == 1 && args->items[0]->type ==tlist)
|
|
{
|
|
int i;
|
|
for(i = 0;i<args->items[0]->data.list.length;i++)
|
|
{
|
|
tobject_t* item= args->items[0]->data.list.items[i];
|
|
if(item->type == tstring)
|
|
{
|
|
if(path == NULL)
|
|
{
|
|
path = string_dups(item->data.string);
|
|
}else{
|
|
string_t* path2 = path_join(path,item->data.string);
|
|
string_free(path);
|
|
path=path2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
int i;
|
|
for(i = 0;i<args->length;i++)
|
|
{
|
|
tobject_t* item= args->items[i];
|
|
if(item->type == tstring)
|
|
{
|
|
if(path == NULL)
|
|
{
|
|
path = string_dups(item->data.string);
|
|
}else{
|
|
string_t* path2 = path_join(path,item->data.string);
|
|
string_free(path);
|
|
path=path2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(path == NULL) return tobject_basic(rt,tnull);
|
|
return tobject_string(rt,path);
|
|
}
|
|
tobject_t* __fs_writealltext_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 1 && args->items[0]->type == tstring && args->items[1]->type == tstring)
|
|
{
|
|
char* fileName = string_dupp(args->items[0]->data.string);
|
|
FILE* f = fopen(fileName,"w");
|
|
if(f)
|
|
{
|
|
string_t* myString = args->items[1]->data.string;
|
|
int totalRead=0;
|
|
int read = 0;
|
|
do {
|
|
read = 1024;
|
|
if( myString->length - totalRead < 1024)
|
|
{
|
|
read = myString->length - totalRead;
|
|
}
|
|
if(read > 0)
|
|
{
|
|
fwrite(myString->text + totalRead,1,read,f);
|
|
totalRead += read;
|
|
}
|
|
} while(read > 0);
|
|
fclose(f);
|
|
}
|
|
free(fileName);
|
|
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __fs_create_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0 && args->items[0]->type == tstring)
|
|
{
|
|
stream_t* strm=stream_file_create(args->items[0]->data.string);
|
|
if(strm != NULL)
|
|
{
|
|
return tobject_fromstream(rt,strm);
|
|
}
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
typedef struct {
|
|
runtime_t* rt;
|
|
tobject_t* exe;
|
|
tobject_t* root;
|
|
tobject_t* addArg;
|
|
tobject_t* std;
|
|
bool stdValue;
|
|
} exec_free_ctx_t;
|
|
void __code_rt_free(tobject_t* o)
|
|
{
|
|
exec_free_ctx_t* ctx = (exec_free_ctx_t*)o->ptr_data;
|
|
free(ctx->root);
|
|
free(ctx->exe);
|
|
free(ctx->addArg);
|
|
free(ctx->std);
|
|
runtime_free(ctx->rt);
|
|
free(ctx);
|
|
}
|
|
tobject_t* __execute_code_rt(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
exec_free_ctx_t* rt2 = (exec_free_ctx_t*)ptr;
|
|
if(rt2->stdValue) {runtime_register_std(rt2->rt);}
|
|
|
|
return runtime_exec(rt2->rt);
|
|
}
|
|
tobject_t* runtime_exec(runtime_t* rt)
|
|
{
|
|
tobject_t* o = rt->program->execute(rt->program,rt->globals);
|
|
if(rt->globals->hasvariable(rt->globals,"main"))
|
|
{
|
|
tobject_t* myObj=rt->globals->getvariable(rt->globals,"main");
|
|
if(myObj->type == tinternalmethod || myObj->type == texternalmethod)
|
|
{
|
|
tobject_freeifzero(o);
|
|
return tobject_call(rt->globals,myObj,&rt->args);
|
|
}
|
|
}
|
|
return o;
|
|
}
|
|
tobject_t* __add_argument(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
runtime_t* rt2 = (runtime_t*)ptr;
|
|
int i;
|
|
for(i=0;i<args->length;i++)
|
|
{
|
|
runtime_add_argument(rt2,args->items[i]);
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __setstd_rt(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
exec_free_ctx_t* ctx = (exec_free_ctx_t*)ptr;
|
|
if(args->length > 0 && args->items[0]->type == tbool)
|
|
{
|
|
ctx->stdValue = args->items[0]->data.boolean;
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __reflection_parse_code(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0 && args->items[0]->type == tstring)
|
|
{
|
|
runtime_t* rt2 = runtime_init();
|
|
runtime_register(rt2,rt->reg);
|
|
runtime_load(rt2,args->items[0]->data.string);
|
|
tobject_t* d = tobject_create(rt);
|
|
tobject_t* d2 = tobject_create(rt);
|
|
d2->data.dict = (dict_t*)rt2->globals->data;
|
|
d2->type = tdict;
|
|
d2->count=65535;
|
|
d->type = tdict;
|
|
d->data.dict = dict_create();
|
|
kvp_t kvp;
|
|
kvp.key = "root";
|
|
kvp.value = d2;
|
|
dict_setkvp(d->data.dict,kvp);
|
|
tobject_t* add_arg = tobject_fromexternalmethod(rt,rt2,__add_argument,NULL);
|
|
kvp.key = "add";
|
|
add_arg->count = 65535;
|
|
kvp.value = add_arg;
|
|
dict_setkvp(d->data.dict,kvp);
|
|
exec_free_ctx_t* __free_Data = (exec_free_ctx_t*)malloc(sizeof(exec_free_ctx_t));
|
|
__free_Data->stdValue=true;
|
|
tobject_t* std = tobject_fromexternalmethod(rt,__free_Data,__setstd_rt,NULL);
|
|
kvp.key = "setstd";
|
|
std->count = 65535;
|
|
kvp.value = std;
|
|
|
|
dict_setkvp(d->data.dict,kvp);
|
|
d->free = __code_rt_free;
|
|
tobject_t* exe = tobject_fromexternalmethod(rt,__free_Data,__execute_code_rt,NULL);
|
|
kvp.key = "run";
|
|
exe->count = 65535;
|
|
kvp.value = exe;
|
|
dict_setkvp(d->data.dict,kvp);
|
|
d->free = __code_rt_free;
|
|
|
|
__free_Data->exe = exe;
|
|
__free_Data->root = d2;
|
|
__free_Data->rt = rt2;
|
|
__free_Data->addArg = add_arg;
|
|
__free_Data->std = std;
|
|
d->ptr_data = __free_Data;
|
|
return d;
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __math_cosh(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,cosh(num));
|
|
}
|
|
tobject_t* __math_sinh(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,sinh(num));
|
|
}
|
|
tobject_t* __math_tanh(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,tanh(num));
|
|
}
|
|
tobject_t* __math_floor(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,floor(num));
|
|
}
|
|
tobject_t* __math_sqrt(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,sqrt(num));
|
|
}
|
|
tobject_t* __math_log(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,log(num));
|
|
}
|
|
tobject_t* __math_log10(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,log10(num));
|
|
}
|
|
tobject_t* __math_ceiling(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,ceil(num));
|
|
}
|
|
tobject_t* __math_cos(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,cos(num));
|
|
}
|
|
tobject_t* __math_acos(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,acos(num));
|
|
}
|
|
tobject_t* __math_sin(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,sin(num));
|
|
}
|
|
tobject_t* __math_tan(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,tan(num));
|
|
}
|
|
tobject_t* __math_atan(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,atan(num));
|
|
}
|
|
tobject_t* __math_asin(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
return tobject_number(rt,asin(num));
|
|
}
|
|
tobject_t* __math_atan2(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
double num2 =0;
|
|
if(args->length > 1 && args->items[0]->type == tnumber && args->items[1]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
num2 = args->items[1]->data.number;
|
|
}
|
|
return tobject_number(rt,atan2(num,num2));
|
|
}
|
|
|
|
tobject_t* __math_pow(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
double num = 0;
|
|
double num2 = 0;
|
|
if(args->length > 0 && args->items[0]->type == tnumber)
|
|
{
|
|
num = args->items[0]->data.number;
|
|
}
|
|
if(args->length > 1 && args->items[1]->type == tnumber)
|
|
{
|
|
num2 = args->items[1]->data.number;
|
|
}
|
|
return tobject_number(rt,pow(num,num2));
|
|
}
|
|
tobject_t* __console_error_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
int i;
|
|
|
|
for(i = 0;i<args->length;i++)
|
|
{
|
|
string_t* s=tobject_tostring(rt->globals,args->items[i]);
|
|
int j;
|
|
for(j=0;j<s->length;j++)
|
|
{
|
|
fputc(s->text[j],stderr);
|
|
}
|
|
string_free(s);
|
|
}
|
|
|
|
return tobject_number(rt,args->length);
|
|
}
|
|
|
|
tobject_t* __console_write_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
int i;
|
|
|
|
for(i = 0;i<args->length;i++)
|
|
{
|
|
string_t* s=tobject_tostring(rt->globals,args->items[i]);
|
|
int j;
|
|
for(j=0;j<s->length;j++)
|
|
{
|
|
fputc(s->text[j],stdout);
|
|
}
|
|
string_free(s);
|
|
}
|
|
|
|
return tobject_number(rt,args->length);
|
|
}
|
|
|
|
|
|
tobject_t* __console_stdin_external_property(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
stream_t* strm=stream_stdin();
|
|
return tobject_fromstream(rt,strm);
|
|
}
|
|
tobject_t* __fs_setworking_external_property(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0 && args->items[0]->type == tstring)
|
|
{
|
|
char* dir = string_dupp(args->items[0]->data.string);
|
|
int res=chdir(dir);
|
|
free(dir);
|
|
return tobject_bool(rt,res==0);
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __fs_getworking_external_property(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
char CWD_PATH[4096];
|
|
char* path=getcwd(CWD_PATH,sizeof(CWD_PATH));
|
|
if(path != NULL)
|
|
{
|
|
string_t* myStr = string_create();
|
|
string_appendp(myStr,path);
|
|
return tobject_string(rt,myStr);
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __console_stdout_external_property(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
stream_t* strm=stream_stdout();
|
|
return tobject_fromstream(rt,strm);
|
|
}
|
|
tobject_t* __console_stderror_external_property(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
stream_t* strm=stream_stderr();
|
|
return tobject_fromstream(rt,strm);
|
|
}
|
|
tobject_t* __fs_unlink_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
int res=0;
|
|
char* fileName = NULL;
|
|
|
|
if(args->length >= 1 && args->items[0]->type == tstring)
|
|
{
|
|
fileName = string_dupp(args->items[0]->data.string);
|
|
}
|
|
|
|
if(fileName != NULL)
|
|
{
|
|
|
|
res=unlink(fileName);
|
|
free(fileName);
|
|
}
|
|
return tobject_bool(rt,res == 0);
|
|
}
|
|
tobject_t* __fs_rmdir_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
int res=0;
|
|
char* dirName = NULL;
|
|
|
|
if(args->length >= 1 && args->items[0]->type == tstring)
|
|
{
|
|
dirName = string_dupp(args->items[0]->data.string);
|
|
}
|
|
|
|
if(dirName != NULL)
|
|
{
|
|
|
|
res=rmdir(dirName);
|
|
free(dirName);
|
|
}
|
|
return tobject_bool(rt,res == 0);
|
|
}
|
|
tobject_t* __fs_mkdir_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
int res=0;
|
|
char* dirName = NULL;
|
|
mode_t mode=0755;
|
|
if(args->length >= 1 && args->items[0]->type == tstring)
|
|
{
|
|
dirName = string_dupp(args->items[0]->data.string);
|
|
}
|
|
if(args->length >= 2 && args->items[1]->type == tnumber)
|
|
{
|
|
mode = (mode_t)args->items[1]->data.number;
|
|
}
|
|
if(dirName != NULL)
|
|
{
|
|
|
|
res=mkdir(dirName,mode);
|
|
free(dirName);
|
|
}
|
|
return tobject_bool(rt,res == 0);
|
|
}
|
|
tobject_t* __console_readln_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
string_t* text = string_create();
|
|
int c = 0;
|
|
while((c=fgetc(stdin)) != '\n' && c != EOF)
|
|
{
|
|
if(c != '\r')
|
|
{
|
|
string_appendc(text,(char)c);
|
|
}
|
|
}
|
|
return tobject_string(rt,text);
|
|
}
|
|
tobject_t* __console_writeln_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
int i;
|
|
|
|
for(i = 0;i<args->length;i++)
|
|
{
|
|
string_t* s=tobject_tostring(rt->globals,args->items[i]);
|
|
int j;
|
|
for(j=0;j<s->length;j++)
|
|
{
|
|
fputc(s->text[j],stdout);
|
|
}
|
|
string_free(s);
|
|
}
|
|
#if defined(WIN32) || defined(_WIN32)
|
|
printf("\r\n");
|
|
#else
|
|
printf("\n");
|
|
#endif
|
|
return tobject_number(rt,args->length);
|
|
}
|
|
tobject_t* __console_errorln_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
int i;
|
|
|
|
for(i = 0;i<args->length;i++)
|
|
{
|
|
string_t* s=tobject_tostring(rt->globals,args->items[i]);
|
|
int j;
|
|
for(j=0;j<s->length;j++)
|
|
{
|
|
fputc(s->text[j],stderr);
|
|
}
|
|
string_free(s);
|
|
}
|
|
#if defined(WIN32) || defined(_WIN32)
|
|
fprintf(stderr,"\r\n");
|
|
#else
|
|
fprintf(stderr,"\n");
|
|
#endif
|
|
return tobject_number(rt,args->length);
|
|
}
|
|
|
|
tobject_t* __console_writetypeln_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
int i;
|
|
|
|
for(i = 0;i<args->length;i++)
|
|
{
|
|
switch(args->items[i]->type)
|
|
{
|
|
case tundef:
|
|
printf("undefined\n");
|
|
break;
|
|
case tnull:
|
|
printf("null\n");
|
|
break;
|
|
case tnumber:
|
|
printf("number\n");
|
|
break;
|
|
case tlist:
|
|
printf("list\n");
|
|
break;
|
|
case tdict:
|
|
printf("dict\n");
|
|
break;
|
|
case tstring:
|
|
printf("string\n");
|
|
break;
|
|
case tinternalmethod:
|
|
printf("internal_method\n");
|
|
break;
|
|
case texternalmethod:
|
|
printf("external_method\n");
|
|
break;
|
|
case tchar:
|
|
printf("char\n");
|
|
break;
|
|
case tbool:
|
|
printf("bool\n");
|
|
break;
|
|
default:
|
|
printf("Unknown: %i\n",(int)args->items[i]->type);
|
|
break;
|
|
}
|
|
}
|
|
#if defined(WIN32) || defined(_WIN32)
|
|
printf("\r\n");
|
|
#else
|
|
printf("\n");
|
|
#endif
|
|
return tobject_number(rt,args->length);
|
|
}
|
|
tobject_t* __create_array_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length == 0)
|
|
{
|
|
return tobject_create_array(rt,0);
|
|
}
|
|
if(args->length == 1 && args->items[0]->type ==tnumber)
|
|
{
|
|
int count = (int)args->items[0]->data.number;
|
|
|
|
return tobject_create_array(rt,count);
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
typedef struct {
|
|
string_t* path;
|
|
fs_entry_filter_t filter;
|
|
} fs_enumerable_ctx_t;
|
|
|
|
tobject_t* __fs_enumerate_entry_getIttr_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
fs_enumerable_ctx_t* ctx = (fs_enumerable_ctx_t*)ptr;
|
|
tobject_t* o = tobject_create(rt);
|
|
o->type = tdict;
|
|
dict_t* d= dict_create();
|
|
ittr_t* ittr=fs_dir_ittr(rt,ctx->path,ctx->filter);
|
|
runtime_create_method_on_dict(d,"getcurrent",rt,ittr,__ls_get_current,NULL);
|
|
runtime_create_method_on_dict(d,"movenext",rt,ittr,__ls_movenext,NULL);
|
|
runtime_create_method_on_dict(d,"reset",rt,ittr,__ls_reset,NULL);
|
|
runtime_create_method_on_dict(d,"dispose",rt,ittr,__ls_free,NULL);
|
|
|
|
|
|
o->data.dict= d;
|
|
return o;
|
|
}
|
|
void __fs_enumerate_entry_getIttr_free(tobject_t* obj)
|
|
{
|
|
fs_enumerable_ctx_t* ctx = (fs_enumerable_ctx_t*)obj->data.external_method.data;
|
|
string_free(ctx->path);
|
|
free(ctx);
|
|
}
|
|
|
|
tobject_t* __fs_enumerate_dirs_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0 && args->items[0]->type == tstring)
|
|
{
|
|
tobject_t* o = tobject_create(rt);
|
|
o->type = tdict;
|
|
o->data.dict = dict_create();
|
|
fs_enumerable_ctx_t* f = (fs_enumerable_ctx_t*)malloc(sizeof(fs_enumerable_ctx_t));
|
|
f->filter = FOLDER;
|
|
f->path = string_dups(args->items[0]->data.string);
|
|
runtime_create_method_on_dict(o->data.dict,"getittr",rt,f,__fs_enumerate_entry_getIttr_external_method,__fs_enumerate_entry_getIttr_free);
|
|
return o;
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
|
|
tobject_t* __fs_enumerate_files_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0 && args->items[0]->type == tstring)
|
|
{
|
|
tobject_t* o = tobject_create(rt);
|
|
o->type = tdict;
|
|
o->data.dict = dict_create();
|
|
fs_enumerable_ctx_t* f = (fs_enumerable_ctx_t*)malloc(sizeof(fs_enumerable_ctx_t));
|
|
f->filter = REGULAR;
|
|
f->path = string_dups(args->items[0]->data.string);
|
|
runtime_create_method_on_dict(o->data.dict,"getittr",rt,f,__fs_enumerate_entry_getIttr_external_method,__fs_enumerate_entry_getIttr_free);
|
|
return o;
|
|
}
|
|
return tobject_basic(rt,tnull);
|
|
}
|
|
tobject_t* __create_dict_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
|
|
tobject_t* o=tobject_create(rt);
|
|
o->data.dict = dict_create();
|
|
o->type = tdict;
|
|
|
|
return o;
|
|
}
|
|
void runtime_register(runtime_t* rt,runtime_reg_t reg)
|
|
{
|
|
rt->reg = reg;
|
|
reg(rt);
|
|
}
|
|
|
|
void runtime_register_std(runtime_t* rt)
|
|
{
|
|
if(rt->hasStd) return;
|
|
rt->hasStd=true;
|
|
tobject_t* __fs = tobject_create(rt);
|
|
__fs->type = tdict;
|
|
__fs->data.dict= dict_create();
|
|
tobject_t* __console = tobject_create(rt);
|
|
__console->type = tdict;
|
|
__console->data.dict= dict_create();
|
|
tobject_t* __reflection = tobject_create(rt);
|
|
__reflection->type = tdict;
|
|
__reflection->data.dict = dict_create();
|
|
tobject_t* __math = tobject_create(rt);
|
|
__math->type = tdict;
|
|
__math->data.dict = dict_create();
|
|
|
|
|
|
runtime_create_method_on_dict(__console->data.dict,"clear",rt,NULL,__console_clear_external_method,NULL);
|
|
runtime_create_method_on_dict(__console->data.dict,"readln",rt,NULL,__console_readln_external_method,NULL);
|
|
|
|
runtime_create_method_on_dict(__console->data.dict,"write",rt,NULL,__console_write_external_method,NULL);
|
|
runtime_create_method_on_dict(__console->data.dict,"getin",rt,NULL,__console_stdin_external_property,NULL);
|
|
runtime_create_method_on_dict(__console->data.dict,"getout",rt,NULL,__console_stdout_external_property,NULL);
|
|
runtime_create_method_on_dict(__console->data.dict,"geterror",rt,NULL,__console_stderror_external_property,NULL);
|
|
runtime_create_method_on_dict(__console->data.dict,"error",rt,NULL,__console_error_external_method,NULL);
|
|
runtime_create_method_on_dict(__console->data.dict,"errorln",rt,NULL,__console_errorln_external_method,NULL);
|
|
|
|
runtime_create_method_on_dict(__console->data.dict,"writeln",rt,NULL,__console_writeln_external_method,NULL);
|
|
runtime_create_method_on_dict(__console->data.dict,"writetypeln",rt,NULL,__console_writetypeln_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"readalltext",rt,NULL,__fs_readalltext_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"parent",rt,NULL,__fs_parent_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"get_extension",rt,NULL,__fs_get_extension_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"get_filename",rt,NULL,__fs_get_filename_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"getworking",rt,NULL,__fs_getworking_external_property,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"setworking",rt,NULL,__fs_setworking_external_property,NULL);
|
|
|
|
|
|
runtime_create_method_on_dict(__fs->data.dict,"writealltext",rt,NULL,__fs_writealltext_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"mkdir",rt,NULL,__fs_mkdir_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"rmdir",rt,NULL,__fs_rmdir_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"unlink",rt,NULL,__fs_unlink_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"enumerate_files",rt,NULL,__fs_enumerate_files_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"enumerate_dirs",rt,NULL,__fs_enumerate_dirs_external_method,NULL);
|
|
|
|
runtime_create_method_on_dict(__fs->data.dict,"create",rt,NULL,__fs_create_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"openread",rt,NULL,__fs_openread_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"append",rt,NULL,__fs_append_external_method,NULL);
|
|
runtime_create_method_on_dict(__fs->data.dict,"combine",rt,NULL,__fs_combine_external_method,NULL);
|
|
|
|
runtime_create_method_on_dict(__fs->data.dict,"openreadwrite",rt,NULL,__fs_openreadwrite_external_method,NULL);
|
|
runtime_create_method_on_dict(__reflection->data.dict,"parse_code",rt,NULL,__reflection_parse_code,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"sin",rt,NULL,__math_sin,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"cos",rt,NULL,__math_cos,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"asin",rt,NULL,__math_asin,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"acos",rt,NULL,__math_acos,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"tan",rt,NULL,__math_tan,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"tanh",rt,NULL,__math_tanh,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"cosh",rt,NULL,__math_cosh,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"sinh",rt,NULL,__math_sinh,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"atan",rt,NULL,__math_atan,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"atan2",rt,NULL,__math_atan2,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"log",rt,NULL,__math_log,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"log10",rt,NULL,__math_log10,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"floor",rt,NULL,__math_floor,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"ceiling",rt,NULL,__math_ceiling,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"sqrt",rt,NULL,__math_sqrt,NULL);
|
|
runtime_create_method_on_dict(__math->data.dict,"pow",rt,NULL,__math_pow,NULL);
|
|
|
|
|
|
rt->globals->setvariable(rt->globals,"fs",__fs);
|
|
rt->globals->setvariable(rt->globals,"console",__console);
|
|
rt->globals->setvariable(rt->globals,"math",__math);
|
|
|
|
rt->globals->setvariable(rt->globals,"reflection",__reflection);
|
|
|
|
#if defined(USE_SDL2)
|
|
runtime_register_sdl(rt);
|
|
#endif
|
|
#if defined(USE_NETWORK)
|
|
runtime_register_network(rt);
|
|
|
|
#endif
|
|
#if defined(USE_MBED)
|
|
runtime_register_mbed(rt);
|
|
#endif
|
|
|
|
}
|
|
|
|
runtime_t* runtime_init()
|
|
{
|
|
runtime_t* rt = (runtime_t*)malloc(sizeof(runtime_t));
|
|
rt->hasStd=false;
|
|
rt->globals = NULL;
|
|
rt->program=NULL;
|
|
rt->reg=NULL;
|
|
list_create(rt,&rt->args,0);
|
|
scope_create_root(rt);
|
|
|
|
tobject_t* __create = tobject_create(rt);
|
|
__create->type = tdict;
|
|
__create->data.dict= dict_create();
|
|
runtime_create_method_on_dict(__create->data.dict,"array",rt,NULL,__create_array_external_method,NULL);
|
|
runtime_create_method_on_dict(__create->data.dict,"dict",rt,NULL,__create_dict_external_method,NULL);
|
|
#if defined(USE_THREADS)
|
|
runtime_register_threads(rt,__create->data.dict);
|
|
#endif
|
|
rt->globals->setvariable(rt->globals,"create",__create);
|
|
|
|
return rt;
|
|
}
|
|
void runtime_add_argument(runtime_t* rt,tobject_t* arg)
|
|
{
|
|
list_add(&rt->args,arg);
|
|
}
|
|
void runtime_free(runtime_t* rt)
|
|
{
|
|
dict_t* d = (dict_t*)rt->globals->data;
|
|
|
|
dict_free(d);
|
|
free(rt->globals);
|
|
if(rt->program != NULL)
|
|
free(rt->program);
|
|
free(rt);
|
|
}
|