tlang-c/libtlang/src/runtime.c

1177 lines
38 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,(size_t (*)(void*,size_t,size_t,void*))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)
{
retarg_t _arg;
_arg.isContinue=false;
_arg.isBreaking=false;
_arg.isReturning=false;
tobject_t* o = rt->program->execute(rt->program,rt->globals,&_arg);
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("array\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);
}
extern void runtime_register_rand(runtime_t* rt);
typedef struct
{
tobject_t* ls;
char* key;
} reflection_get_dict_entries_entry_t;
tobject_t* __reflection_get_dict_entry(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length >= 2 && args->items[0]->type == tdict && args->items[1]->type == tstring)
{
char* kvp = string_dupp(args->items[1]->data.string);
if(dict_haskey(args->items[0]->data.dict,kvp))
{
tobject_t* v=dict_getkvp(args->items[0]->data.dict,kvp)->value;
free(kvp);
return v;
}
free(kvp);
return tobject_basic(rt,tundef);
}
return tobject_basic(rt,tnull);
}
tobject_t* __reflection_set_dict_entry(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length >= 3 && args->items[0]->type == tdict && args->items[1]->type == tstring)
{
char* _kvp = string_dupp(args->items[1]->data.string);
kvp_t kvp;
kvp.key=_kvp;
kvp.value = args->items[2];
dict_setkvp(args->items[0]->data.dict,kvp);
free(_kvp);
}
return tobject_basic(rt,tnull);
}
tobject_t* __reflection_get_dict_entries_getname(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(ptr != NULL)
{
reflection_get_dict_entries_entry_t* da = (reflection_get_dict_entries_entry_t*)ptr;
return tobject_stringp(rt,da->key);
}
return tobject_stringp(rt,"");
}
tobject_t* __reflection_get_dict_entries_getvalue(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(ptr != NULL)
{
reflection_get_dict_entries_entry_t* da = (reflection_get_dict_entries_entry_t*)ptr;
if(dict_haskey(da->ls->data.dict,da->key))
{
return dict_getkvp(da->ls->data.dict,da->key)->value;
}
}
return tobject_basic(rt,tundef);
}
tobject_t* __reflection_get_dict_entries_setvalue(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(ptr != NULL && args->length > 0)
{
reflection_get_dict_entries_entry_t* da = (reflection_get_dict_entries_entry_t*)ptr;
kvp_t kvp;
kvp.key = da->key;
kvp.value = args->items[0];
dict_setkvp(da->ls->data.dict,kvp);
}
return tobject_basic(rt,tnull);
}
void __reflection_get_dictentries_drop_ptr_data(tobject_t* d)
{
tobject_rmref((tobject_t*)d->ptr_data);
}
void __reflection_get_dict_entries_entry_free(tobject_t* d)
{
free(d->ptr_data);
}
tobject_t* __reflection_get_dict_entries(runtime_t* rt,void* ptr,list_tobject_t* args)
{
tobject_t* ls = tobject_create_array(rt,0);
ls->free=NULL;
ls->ptr_data=NULL;
if(args->length >= 1 && args->items[0]->type == tdict)
{
tobject_t* data = args->items[0];
ls->ptr_data = data;
ls->free = __reflection_get_dictentries_drop_ptr_data;
tobject_addref(data);
int i;
for(i = 0;i<data->data.dict->length;i++)
{
tobject_t* kvp = tobject_create(rt);
kvp->type = tdict;
kvp->data.dict = dict_create();
reflection_get_dict_entries_entry_t* __entry_data = (reflection_get_dict_entries_entry_t*)malloc(sizeof(reflection_get_dict_entries_entry_t));
__entry_data->key = data->data.dict->items[i].key;
__entry_data->ls = data;
kvp->ptr_data = __entry_data;
runtime_create_method_on_object(kvp,"getname",rt,__entry_data,__reflection_get_dict_entries_getname,NULL);
runtime_create_method_on_object(kvp,"setvalue",rt,__entry_data,__reflection_get_dict_entries_setvalue,NULL);
runtime_create_method_on_object(kvp,"getvalue",rt,__entry_data,__reflection_get_dict_entries_getvalue,NULL);
kvp->free = __reflection_get_dict_entries_entry_free;
list_add(&ls->data.list,kvp);
}
}
return ls;
}
tobject_t* __reflection_arg_count(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length >= 1 && args->items[0]->type == tinternalmethod)
{
return tobject_number(rt,(double)args->items[0]->data.internal_method.closure->data.closure_node.argNames.count);
}
if(args->length >= 1 && args->items[0]->type == texternalmethod)
{
return tobject_number(rt,-1);
}
return tobject_basic(rt,tnull);
}
tobject_t* __reflection_call(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length >= 2 && (args->items[0]->type == tinternalmethod || args->items[0]->type == texternalmethod) && args->items[1]->type == tlist)
{
return tobject_call(rt->globals,args->items[0],&args->items[1]->data.list);
}
return tobject_basic(rt,tnull);
}
#if defined(USE_JANSSON)
extern void runtime_register_json(runtime_t* rt);
#endif
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();
tobject_t* __rt = tobject_create(rt);
__rt->type = tdict;
__rt->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_object(__reflection,"get_dict_entries",rt,NULL,__reflection_get_dict_entries,NULL);
runtime_create_method_on_object(__reflection,"get_dict_entry",rt,NULL,__reflection_get_dict_entry,NULL);
runtime_create_method_on_object(__reflection,"set_dict_entry",rt,NULL,__reflection_set_dict_entry,NULL);
runtime_create_method_on_object(__reflection,"arg_count",rt,NULL,__reflection_arg_count,NULL);
runtime_create_method_on_object(__reflection,"call",rt,NULL,__reflection_call,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);
tobject_t* __version = tobject_create(rt);
__version->type = tdict;
__version->data.dict = dict_create();
runtime_create_number_on_object(__version,"major",rt,TLANG_MAJOR);
runtime_create_number_on_object(__version,"minor",rt,TLANG_MINOR);
runtime_create_number_on_object(__version,"patch",rt,TLANG_PATCH);
runtime_create_number_on_object(__version,"build",rt,TLANG_BUILD);
kvp_t kvp2;
kvp2.key="version";
kvp2.value = __version;
dict_setkvp(__rt->data.dict,kvp2);
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);
rt->globals->setvariable(rt->globals,"rt",__rt);
#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
#if defined(USE_JANSSON)
runtime_register_json(rt);
#endif
runtime_register_rand(rt);
}
tobject_t* __typeof_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length >= 1)
{
switch(args->items[0]->type)
{
case tundef:
return tobject_stringp(rt,"undefined");
case tnull:
return tobject_stringp(rt,"null");
case tnumber:
return tobject_stringp(rt,"number");
case tlist:
return tobject_stringp(rt,"array");
case tdict:
return tobject_stringp(rt,"dict");
case tstring:
return tobject_stringp(rt,"string");
case tinternalmethod:
return tobject_stringp(rt,"internal_method");
case texternalmethod:
return tobject_stringp(rt,"external_method");
case tchar:
return tobject_stringp(rt,"char");
case tbool:
return tobject_stringp(rt,"bool");
default:
{
string_t* __s = string_create();
string_appendp(__s,"Unknown: ");
string_appendn(__s,(int)args->items[0]->type);
return tobject_string(rt,__s);
}
}
}
return tobject_stringp(rt,"missing_argument");
}
#if defined(USE_THREADS)
extern void runtime_register_threads(runtime_t* rt,dict_t* create);
#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);
tobject_t* typeof_func = tobject_fromexternalmethod(rt,NULL,__typeof_external_method,NULL);
rt->globals->setvariable(rt->globals,"typeof",typeof_func);
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);
}