struct mb_interpreter_t* bas = 0;
...
rtnval = mb_load_string(AT bas, pgm);
MBAPI int mb_load_string(mb_interpreter_t* s, const char* l);
mb_assert(s && s->parsing_context);
jrs@laptop:~/mybasic/my_basic-master$ ./mybasic
MY-BASIC Interpreter Shell - 1.0.0050.
Copyright (C) 2011 - 2015 W. Renxin. All Rights Reserved.
For more information, see https://github.com/paladin-t/my_basic/.
Input HELP and hint enter to view help information.
]PRINT "HellO"
]RUN
HellO
]
3. String pushing. Pelase git a updated revision and use 'mb_memdup' to generate a MY-BASIC managable string before pushing, you can find more information about this API in the ref doc pdf or search for it in https://github.com/paladin-t/my_basic/wiki/File-module for a demo usage.
This function pushes an argument of char* to an interpreter structure.
#include "my_basic.c"
static struct mb_interpreter_t* bas = 0;
int main (int argc, char** argv) {
int retval;
mb_open(&bas);
retval = mb_load_string(bas,"print \"Hello, World!\n\"");
retval = mb_run(bas);
return retval;
}
The mb_assert() function doesn't seem to be exported in the API version of MY-BASIC.
FOR i = 3 TO 5000
f = 1
FOR j = 2 TO SQR(i)
IF i MOD j = 0 THEN f = 0 : EXIT
NEXT j
IF f = 1 THEN PRINT i," "
NEXT i
PRINT ,
3. Use mb_pop_XXX to retrieve values, and mb_push_XXX to return values, see the file extension https://github.com/paladin-t/my_basic/wiki/File-module for demo; search for 'mb_pop_'.
PRAGMA OPTIONS -I/home/jrs/sb/source
PRAGMA LDFLAGS scriba pthread
PRAGMA INCLUDE scriba.h getopt.h
PROTO scriba_destroy
DECLARE pProgram TYPE pSbProgram
DECLARE pVariable TYPE pSbData
pProgram = scriba_new(malloc,free)
ok = scriba_LoadConfiguration(pProgram,"/etc/scriba/basic.conf")
ok = scriba_SetFileName(pProgram, "E05.sb")
ok = scriba_LoadSourceProgram(pProgram)
ok = scriba_Run(pProgram,"")
vsn = scriba_LookupVariableByName(pProgram, "main::dbstr")
ok = scriba_GetVariable(pProgram, vsn, &pVariable)
dbstr$ = pVariable[0].v.s
SPLIT dbstr$ BY "|" TO row$ SIZE cnt
FOR x = 0 TO cnt-1
PRINT row$[x]
NEXT x
Ability of retrieving variables from host is useful in some case. I consider to implement not only retrieving, but also setting break point and single step evaluating; that will make up a debug API set.
Script BASIC has a debugging mode (internal preprocessor) that Dave (SB VB/COM contributor) took advantage of in the IDE/Debugger he wrote.
a = 123
b = 1.23
c$ = "One,Two,Three"
PRINT a;
PRINT b;
PRINT c$;
a = 123
b = 1.23
c$ = "One,Two,Three"
I just noticed your profile on Github.
a = 0
b = 0.0
c$ = ""
That still doesn't solve the Linux 64 bit version failing on all mb_set operations. :-[
a = 0
b = 0.0
c$ = ""
No luck with your change to fix the Windows mb_setstr() function. Here is my change to the function per your suggestion.Code: C
besFUNCTION(mbas_setstr) DIM AS mb_value_t mbval; DIM AS const char PTR usrval; DIM AS const char PTR varname; besARGUMENTS("zz") AT varname, AT usrval besARGEND mbval.type = MB_DT_STRING; mbval.value.string = usrval; besRETURN_LONG(mb_debug_set(bas, varname, mbval)); besEND
C:\sb22\mybasic>scriba mbvarset.sb
Got Here
Assertion failed: 0 && "Memory already released", file my_basic.c, line 3889
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
C:\sb22\mybasic>
There seems to be a bug in SB using the "zi" combo. If I reverse them it works. >:(
a = 0
b = 0.0
c$ = ""
Can you export a function like LIST but the return value would be a multi-line string version of the the program? If we had this ability, one could retrieve the current program into a SB string, mb_reset the MY-BASIC workspace and mb_load_str an edited version of the script.
jrs@laptop:~/sb/sb22/modules$ nm mb.so
U acosf@@GLIBC_2.2.5
0000000000006f10 t _append_char_to_symbol
U asinf@@GLIBC_2.2.5
U __assert_fail
U atanf@@GLIBC_2.2.5
0000000000214940 b bas
0000000000003010 T bootmodu
0000000000214938 B __bss_start
0000000000214960 b buf.6267
0000000000009340 t _calc_expression
U ceilf@@GLIBC_2.2.5
0000000000006fc0 t _clear_array
0000000000003a20 t _compare_numbers
00000000000079a0 t _core_add
0000000000003de0 t _core_and
0000000000003fe0 t _core_close_bracket
000000000000bb30 t _core_dim
0000000000004ef0 t _core_div
000000000000ac40 t _core_do
0000000000003930 t _core_dummy_assign
0000000000003b60 t _core_else
0000000000003b90 t _core_elseif
0000000000004910 t _core_end
0000000000003b30 t _core_endif
0000000000006a40 t _core_equal
0000000000005440 t _core_exit
000000000000b0c0 t _core_for
0000000000007d80 t _core_gosub
00000000000052f0 t _core_goto
0000000000006390 t _core_greater
0000000000005cd0 t _core_greater_equal
000000000000b630 t _core_if
00000000000066f0 t _core_less
0000000000006030 t _core_less_equal
000000000000a5a0 t _core_let
00000000002141a0 d _core_libs
000000000000e8d0 t _core_mem
00000000000041e0 t _core_min
0000000000004be0 t _core_mod
0000000000004040 t _core_mul
000000000000d7b0 t _core_neg
0000000000006df0 t _core_next
000000000000e950 t _core_not
0000000000005990 t _core_not_equal
0000000000004010 t _core_open_bracket
0000000000003bf0 t _core_or
00000000000043a0 t _core_pow
0000000000007250 t _core_return
00000000000039c0 t _core_step
0000000000003bc0 t _core_then
00000000000039f0 t _core_to
0000000000003960 t _core_until
0000000000003990 t _core_wend
000000000000af00 t _core_while
U cosf@@GLIBC_2.2.5
U __ctype_b_loc
U __ctype_toupper_loc
0000000000007fe0 t _cut_symbol
00000000000076c0 t _destroy_object
0000000000007700 t _destroy_object_non_syntax
00000000000073b0 t _dispose_object
0000000000214598 d _DYNAMIC
0000000000214938 D _edata
00000000002149a0 B _end
0000000000214420 d _ERR_DESC
000000000000a9b0 t _execute_statement
U exit
0000000000214988 b _exp_assign
U exp@@GLIBC_2.2.5
0000000000005930 t _extract_string
U fclose
U fgets
0000000000003030 T finimodu
U floorf@@GLIBC_2.2.5
U fopen
U fread
U free
U fseek
U ftell
U fwrite
0000000000008fd0 t _get_array_index
0000000000002eb0 t _get_inputer.part.23
0000000000002ed0 t _get_printer.part.24
0000000000005660 t _get_priority_index
0000000000005480 t _get_size_of.part.11
0000000000214728 d _GLOBAL_OFFSET_TABLE_
0000000000007340 t _ht_clear
0000000000003910 t _ht_cmp_int
0000000000004380 t _ht_cmp_string
0000000000008ee0 t _ht_create.constprop.74
00000000000078a0 t _ht_destroy
0000000000005270 t _ht_find
0000000000007800 t _ht_foreach
00000000000048e0 t _ht_hash_int
0000000000004890 t _ht_hash_string
0000000000007de0 t _ht_set_or_insert
0000000000006e50 t _internal_object_to_public_value
00000000000054e0 t _is_expression_terminal
0000000000004700 t _is_flow
0000000000004810 t _is_identifier_char
0000000000004600 t _is_operator
0000000000004850 t _is_operator_char
00000000000058d0 t _is_string
U logf@@GLIBC_2.2.5
00000000000072e0 t _ls_clear
00000000000038f0 t _ls_cmp_data
0000000000003900 t _ls_cmp_extra
0000000000004390 t _ls_cmp_extra_string
0000000000007ce0 t _ls_create_node
0000000000007860 t _ls_destroy
0000000000002e90 t _ls_empty.part.22
0000000000007760 t _ls_foreach
0000000000007190 t _ls_free_extra
00000000000071d0 t _ls_popback
0000000000007d30 t _ls_pushback
00000000000070b0 t _ls_try_remove
0000000000002ef0 T ltrim
U malloc
0000000000214980 b _mb_allocated
0000000000003130 T mbas_close
0000000000003090 T mbas_dispose
00000000000033c0 T mbas_getdbl
0000000000003320 T mbas_getint
0000000000003460 T mbas_getstr
0000000000003040 T mbas_init
0000000000003200 T mbas_load_file
0000000000003180 T mbas_load_str
00000000000030e0 T mbas_open
00000000000032d0 T mbas_reset
0000000000003280 T mbas_run
0000000000003660 T mbas_setdbl
0000000000003530 T mbas_setint
00000000000037a0 T mbas_setstr
000000000000d280 T mb_attempt_close_bracket
000000000000ce10 T mb_attempt_func_begin
000000000000cea0 T mb_attempt_func_end
000000000000d1e0 T mb_attempt_open_bracket
000000000000c940 T mb_close
000000000000f820 T mb_debug_get
000000000000f8f0 T mb_debug_set
000000000000f980 T mb_debug_set_stepped_handler
000000000000c340 T mb_dispose
000000000000bfd0 T mb_dispose_value
0000000000006f80 t mb_free
000000000000f9e0 T mb_get_error_desc
000000000000f9b0 T mb_get_last_error
00000000000045a0 T mb_gets
000000000000d350 T mb_has_arg
000000000000c090 T mb_init
000000000000fbf0 T mb_load_file
000000000000fa20 T mb_load_string
0000000000007950 t mb_malloc
000000000000ff60 T mb_memdup
000000000000c5f0 T mb_open
000000000000d580 T mb_pop_int
000000000000d600 T mb_pop_real
000000000000d680 T mb_pop_string
000000000000d6f0 T mb_pop_usertype
000000000000d3c0 T mb_pop_value
000000000000e870 T mb_push_int
000000000000f120 T mb_push_real
000000000000f220 T mb_push_string
000000000000f770 T mb_push_usertype
000000000000d760 T mb_push_value
000000000000cde0 T mb_register_func
000000000000cdf0 T mb_remove_func
000000000000ce00 T mb_remove_reserved_func
000000000000cb40 T mb_reset
000000000000fd20 T mb_run
000000000000fed0 T mb_set_error_handler
000000000000ff30 T mb_set_inputer
000000000000ff00 T mb_set_printer
0000000000004560 t mb_strupr
000000000000f7d0 T mb_suspend
000000000000c020 T mb_ver
000000000000c030 T mb_ver_string
U memcpy
U memmove
U memset
0000000000214990 b _OBJ_BOOL_FALSE
0000000000214998 b _OBJ_BOOL_TRUE
0000000000011550 r _OBJ_INT_ZERO
0000000000007e80 t _open_constant
0000000000008940 t _parse_char
U pow@@GLIBC_2.2.5
00000000000113e0 r _PRECEDE_TABLE
0000000000011320 r __PRETTY_FUNCTION__.5458
00000000000112a7 r __PRETTY_FUNCTION__.5473
00000000000112e3 r __PRETTY_FUNCTION__.5479
000000000001109e r __PRETTY_FUNCTION__.5488
0000000000011056 r __PRETTY_FUNCTION__.5499
0000000000010ec4 r __PRETTY_FUNCTION__.5507
00000000000110cb r __PRETTY_FUNCTION__.5512
000000000001104a r __PRETTY_FUNCTION__.5519
0000000000011350 r __PRETTY_FUNCTION__.5525
0000000000011340 r __PRETTY_FUNCTION__.5534
0000000000011330 r __PRETTY_FUNCTION__.5545
0000000000011293 r __PRETTY_FUNCTION__.5588
0000000000010e30 r __PRETTY_FUNCTION__.5600
0000000000010cb0 r __PRETTY_FUNCTION__.5609
0000000000010c66 r __PRETTY_FUNCTION__.5624
0000000000010c90 r __PRETTY_FUNCTION__.5632
0000000000011372 r __PRETTY_FUNCTION__.5641
000000000001139b r __PRETTY_FUNCTION__.5645
0000000000011114 r __PRETTY_FUNCTION__.5681
0000000000011100 r __PRETTY_FUNCTION__.5686
00000000000110e0 r __PRETTY_FUNCTION__.5698
00000000000111b0 r __PRETTY_FUNCTION__.5704
0000000000011240 r __PRETTY_FUNCTION__.5733
0000000000010de0 r __PRETTY_FUNCTION__.5780
00000000000112d0 r __PRETTY_FUNCTION__.5785
0000000000010dd2 r __PRETTY_FUNCTION__.5789
0000000000010dfe r __PRETTY_FUNCTION__.5793
0000000000010ab0 r __PRETTY_FUNCTION__.5824
0000000000010aff r __PRETTY_FUNCTION__.5836
0000000000010af0 r __PRETTY_FUNCTION__.5851
0000000000010ae1 r __PRETTY_FUNCTION__.5875
0000000000010ad0 r __PRETTY_FUNCTION__.5907
0000000000010b0b r __PRETTY_FUNCTION__.5937
00000000000112c0 r __PRETTY_FUNCTION__.5945
00000000000111e6 r __PRETTY_FUNCTION__.5950
0000000000011180 r __PRETTY_FUNCTION__.5957
0000000000011190 r __PRETTY_FUNCTION__.5972
0000000000011170 r __PRETTY_FUNCTION__.5988
0000000000010f70 r __PRETTY_FUNCTION__.6000
0000000000010f8a r __PRETTY_FUNCTION__.6006
00000000000111f3 r __PRETTY_FUNCTION__.6015
0000000000011200 r __PRETTY_FUNCTION__.6022
00000000000110c0 r __PRETTY_FUNCTION__.6028
00000000000110b0 r __PRETTY_FUNCTION__.6033
0000000000011210 r __PRETTY_FUNCTION__.6044
0000000000011070 r __PRETTY_FUNCTION__.6065
0000000000011220 r __PRETTY_FUNCTION__.6073
00000000000111d0 r __PRETTY_FUNCTION__.6080
0000000000010ff0 r __PRETTY_FUNCTION__.6086
0000000000011140 r __PRETTY_FUNCTION__.6092
0000000000010b80 r __PRETTY_FUNCTION__.6104
0000000000011080 r __PRETTY_FUNCTION__.6118
0000000000011260 r __PRETTY_FUNCTION__.6134
0000000000011041 r __PRETTY_FUNCTION__.6154
0000000000010fa0 r __PRETTY_FUNCTION__.6166
0000000000011251 r __PRETTY_FUNCTION__.6181
0000000000010e42 r __PRETTY_FUNCTION__.6195
0000000000010cbb r __PRETTY_FUNCTION__.6206
0000000000010ce0 r __PRETTY_FUNCTION__.6213
0000000000010c80 r __PRETTY_FUNCTION__.6218
0000000000011310 r __PRETTY_FUNCTION__.6224
0000000000010ca0 r __PRETTY_FUNCTION__.6233
0000000000010e16 r __PRETTY_FUNCTION__.6242
0000000000010cc8 r __PRETTY_FUNCTION__.6251
00000000000113b0 r __PRETTY_FUNCTION__.6260
0000000000011393 r __PRETTY_FUNCTION__.6272
0000000000011367 r __PRETTY_FUNCTION__.6277
000000000001135f r __PRETTY_FUNCTION__.6287
0000000000010cd7 r __PRETTY_FUNCTION__.6297
0000000000010c70 r __PRETTY_FUNCTION__.6307
0000000000010c50 r __PRETTY_FUNCTION__.6329
0000000000010c30 r __PRETTY_FUNCTION__.6337
0000000000010c10 r __PRETTY_FUNCTION__.6345
0000000000010bf0 r __PRETTY_FUNCTION__.6354
0000000000010be5 r __PRETTY_FUNCTION__.6363
0000000000010bda r __PRETTY_FUNCTION__.6372
0000000000010bce r __PRETTY_FUNCTION__.6387
0000000000010bc0 r __PRETTY_FUNCTION__.6402
0000000000010bb0 r __PRETTY_FUNCTION__.6416
0000000000010ba1 r __PRETTY_FUNCTION__.6433
0000000000010b6d r __PRETTY_FUNCTION__.6442
0000000000010b60 r __PRETTY_FUNCTION__.6451
0000000000010b51 r __PRETTY_FUNCTION__.6460
0000000000010b40 r __PRETTY_FUNCTION__.6469
0000000000010b26 r __PRETTY_FUNCTION__.6478
0000000000010b17 r __PRETTY_FUNCTION__.6493
0000000000010a99 r __PRETTY_FUNCTION__.6508
0000000000010a92 r __PRETTY_FUNCTION__.6516
0000000000010a87 r __PRETTY_FUNCTION__.6526
0000000000010a7a r __PRETTY_FUNCTION__.6536
0000000000010a6d r __PRETTY_FUNCTION__.6545
0000000000010a50 r __PRETTY_FUNCTION__.6551
0000000000010a30 r __PRETTY_FUNCTION__.6556
0000000000010a10 r __PRETTY_FUNCTION__.6560
00000000000109f0 r __PRETTY_FUNCTION__.6566
00000000000109df r __PRETTY_FUNCTION__.6572
00000000000109d0 r __PRETTY_FUNCTION__.6578
0000000000011380 r __PRETTY_FUNCTION__.6594
0000000000010e51 r __PRETTY_FUNCTION__.6601
0000000000010e5b r __PRETTY_FUNCTION__.6620
0000000000010e65 r __PRETTY_FUNCTION__.6632
0000000000010e6f r __PRETTY_FUNCTION__.6644
0000000000010e79 r __PRETTY_FUNCTION__.6663
0000000000010e83 r __PRETTY_FUNCTION__.6682
0000000000010e90 r __PRETTY_FUNCTION__.6694
0000000000010eb0 r __PRETTY_FUNCTION__.6701
0000000000010ece r __PRETTY_FUNCTION__.6711
0000000000010ed8 r __PRETTY_FUNCTION__.6727
0000000000010ee4 r __PRETTY_FUNCTION__.6757
0000000000010eef r __PRETTY_FUNCTION__.6788
0000000000010f00 r __PRETTY_FUNCTION__.6819
0000000000010f20 r __PRETTY_FUNCTION__.6850
0000000000010f40 r __PRETTY_FUNCTION__.6881
0000000000010f50 r __PRETTY_FUNCTION__.6910
0000000000010f5a r __PRETTY_FUNCTION__.6922
0000000000010f63 r __PRETTY_FUNCTION__.6935
0000000000010f80 r __PRETTY_FUNCTION__.6955
0000000000010f96 r __PRETTY_FUNCTION__.6983
0000000000010faf r __PRETTY_FUNCTION__.6998
0000000000010fb8 r __PRETTY_FUNCTION__.7013
0000000000010fc3 r __PRETTY_FUNCTION__.7020
0000000000010fd0 r __PRETTY_FUNCTION__.7027
0000000000010fdb r __PRETTY_FUNCTION__.7034
0000000000011001 r __PRETTY_FUNCTION__.7052
000000000001100b r __PRETTY_FUNCTION__.7069
0000000000011014 r __PRETTY_FUNCTION__.7076
000000000001101f r __PRETTY_FUNCTION__.7086
000000000001102a r __PRETTY_FUNCTION__.7097
0000000000011036 r __PRETTY_FUNCTION__.7108
0000000000011273 r __PRETTY_FUNCTION__.7120
000000000001127c r __PRETTY_FUNCTION__.7131
0000000000011288 r __PRETTY_FUNCTION__.7138
000000000001129c r __PRETTY_FUNCTION__.7148
00000000000112b4 r __PRETTY_FUNCTION__.7157
00000000000112ef r __PRETTY_FUNCTION__.7165
00000000000112fc r __PRETTY_FUNCTION__.7172
0000000000011306 r __PRETTY_FUNCTION__.7181
0000000000010cef r __PRETTY_FUNCTION__.7188
0000000000010cf8 r __PRETTY_FUNCTION__.7204
0000000000010d01 r __PRETTY_FUNCTION__.7220
0000000000010d0a r __PRETTY_FUNCTION__.7236
0000000000010d15 r __PRETTY_FUNCTION__.7252
0000000000010d1f r __PRETTY_FUNCTION__.7268
0000000000010d28 r __PRETTY_FUNCTION__.7284
0000000000010d33 r __PRETTY_FUNCTION__.7300
0000000000010d3c r __PRETTY_FUNCTION__.7310
0000000000010d45 r __PRETTY_FUNCTION__.7326
0000000000010d4e r __PRETTY_FUNCTION__.7342
0000000000010d57 r __PRETTY_FUNCTION__.7358
0000000000010d61 r __PRETTY_FUNCTION__.7374
0000000000010d6b r __PRETTY_FUNCTION__.7390
0000000000010d75 r __PRETTY_FUNCTION__.7406
0000000000010d7e r __PRETTY_FUNCTION__.7422
0000000000010d87 r __PRETTY_FUNCTION__.7438
0000000000010d90 r __PRETTY_FUNCTION__.7451
0000000000010d99 r __PRETTY_FUNCTION__.7464
0000000000010da3 r __PRETTY_FUNCTION__.7477
0000000000010dac r __PRETTY_FUNCTION__.7491
0000000000010db5 r __PRETTY_FUNCTION__.7507
0000000000010dc0 r __PRETTY_FUNCTION__.7521
0000000000010dc9 r __PRETTY_FUNCTION__.7535
0000000000010df3 r __PRETTY_FUNCTION__.7552
0000000000010e0b r __PRETTY_FUNCTION__.7574
U printf
00000000000055a0 t _public_value_to_internal_object
U rand
0000000000007f20 t _register_func
0000000000008da0 t _remove_func
00000000000054b0 t _remove_source_object
0000000000002f50 T rtrim
0000000000004950 t _set_current_error
0000000000002e70 t _set_error_pos.part.8
U sinf@@GLIBC_2.2.5
0000000000004990 t _skip_struct
0000000000004ad0 t _skip_to
U __sprintf_chk
U sqrtf@@GLIBC_2.2.5
U __stack_chk_fail
000000000000e710 t _std_abs
000000000000deb0 t _std_acos
000000000000eaa0 t _std_asc
000000000000e010 t _std_asin
000000000000dd50 t _std_atan
000000000000ed80 t _std_ceil
000000000000f6d0 t _std_chr
000000000000e2d0 t _std_cos
U stderr
000000000000dbd0 t _std_exp
000000000000ec60 t _std_fix
000000000000eea0 t _std_floor
U stdin
000000000000cee0 t _std_input
000000000000f5f0 t _std_left
000000000000ea10 t _std_len
0000000000214000 d _std_libs
000000000000da70 t _std_log
000000000000f4a0 t _std_mid
000000000000a0e0 t _std_print
000000000000f3a0 t _std_right
000000000000f180 t _std_rnd
000000000000eb30 t _std_round
000000000000efc0 t _std_sgn
000000000000e430 t _std_sin
000000000000e590 t _std_sqr
000000000000f280 t _std_str
000000000000e170 t _std_tan
000000000000d960 t _std_val
U strcat
U strcmp
U strcpy
U strlen
U strtod
U strtol
U tanf@@GLIBC_2.2.5
0000000000002fe0 T trim
0000000000006da0 t _try_clear_intermediate_value.isra.19
0000000000008f60 t _try_get_value.constprop.75
0000000000003000 T versmodu
jrs@laptop:~/sb/sb22/modules$
It's in main.c as well as _list_program.
screen (512,512,"Fractal")
bx=0
by=0
bw=256*2
bh=256*2
sx=-2.2
sy=-1.7
sw=3.4
sh=3.4
cls
for x=bx to bx+bw
for y=by to by+bh
gx=(x-bx)/bw*sw+sx
gy=(y-by)/bh*sh+sy
zx=gx
zy=gy
for c=0 to 255
col = c
nzx=zx*zx - zy*zy + gx
zy=2*zx*zy+gy
zx=nzx
if zx*zx + zy*zy > 4 then col = c: exit
next
r = col*256+col
v = col*256+col*32
b = col*256+col*64
ink (r,v,b)
pset (x,y)
sync
next
next
sync
do
sleep (15)
until keypressed=true
pi = 3.141
Oh, I found one issue: you can't assign real numbers to variables anymore.Quite a bug... Fixed in latest revision. Thanks for telling me.
I'm glad you haven't given up on AllegroBASIC. I plan to update the Script BASIC extension module of My-BASIC when you guys feel it's stable.I believe it needs some time to test it and make this new feature robust. I plan to implement an OOP paradigm also, but won't start until exist mechanism stable, considering it takes about two years to decide to make sub routine (or function) from an idea... Keep going guys.
Thanks for fixing the bug. It works again as expected.Oh, I found one issue: you can't assign real numbers to variables anymore.Quite a bug... Fixed in latest revision. Thanks for telling me.
def plusone(a)
if a <= 10 then
a = a + 1
print a, "\n"
plusone(a)
endif
enddef
plusone(1)
I tried a simple SUB recursion test and it didn't work and segmentation faulted.I'll look over to fix it, and post it when it's done. Thanks for report.
Seems to work. Have you also tested it with FUNCTIONs returning a value in a recursive mode?
Can you show an example of CLASS/ENDCLASS?
I thought I would give your precompiled Windows version a try in Wine and notice this error with a simple FOR/NEXT structure.
EDIT: Hm, I tried compiling with GCC and it works, seems only TCC to be affected ...
def drawbackground()
...
enddef
If you call now the sub I got a memory allocation error.def drawbackground(void)
...
enddef
And this can be called likedrawbackground()
without any errors.l = list(1, 2, 3)
d = dict("hah", l)
c = clone(d)
print get(get(c, "hah"), 0);
i = iterator(get(c, "hah"))
while move_next(i)
print get(i);
wend
l = list()
push(l, foo())
a = clone(l)
l = nil
print pop(a);
Is there anything I have to call now additionally to the mb_close and mb_dispose functions? Now everything works fine except when the interpreter closes then I got a memory allocation error. (I think it's that, because I got a German error description: "Speicherzugriffsfehler".)
Ah, "segmentation fault" is the correct term. Sorry, guys. I just compiled the latest version and still got the same error message. I compiled it with TCC.Is there anything I have to call now additionally to the mb_close and mb_dispose functions? Now everything works fine except when the interpreter closes then I got a memory allocation error. (I think it's that, because I got a German error description: "Speicherzugriffsfehler".)
Nothing additionally is needed, I didn't change "mb_xxx" function disciplines. Try the latest revision in which I've corrected some uninitialized memory issues please, it might solve the issue. It doesn't say any error when exiting, I compiled it with VC, PellesC, TCC on Windows, I'll test it with GCC and Clang on Linux and OSX later. Did it say "Speicherzugriffsfehler" with GCC?
Cybermonkey342,Hm, I don't think so. AllegroBASIC is just a programm which calls a few Allegro functions and bind them to MY-BASIC.
Will I be able to embed AllegroBASIC in Script BASIC like Tony's version?
int main(int argc, char **argv)
{
atexit(_on_exit);
_on_startup();
if (argc>1) {
if(mb_load_file(bas, argv[1]) == MB_FUNC_OK)
mb_run(bas);
}
else {
printf ("AllegroBASIC 0.2\nUsage: allegrobasic[.exe] script.bas.\n");
}
return 0;
}
t = ticks()
for i = 0 to 10000000
s = s + i
next
t = ticks() - t
print t / 1000, "s";
I'll deal with it. For the moment uncomment the "MB_ENABLE_GC" macro in "my_basic.h" to get around it.
a = 0
b = 0.0
c$ = ""
class animal
def speak(a)
print "default" + a;
enddef
endclass
class cat(animal)
def speak(a)
print "meow" + a;
enddef
endclass
class dog(animal)
def speak(a)
print "bark" + a;
enddef
endclass
c = new(cat)
d = new(dog)
c.speak("!")
d.speak("!")
f = lambda (x, y) (return x * x + y * y)
print f(3, 4);
' mousetest
KEY_ESC = 59
screen (640,480,"Mousetest")
hidemouse
do
cls
drawtext (100,100,"MouseX: "+str(mouseX))
drawtext (100,112,"MouseY: "+str(mouseY))
drawtext (100,124,"MouseButton: "+str(mousebutton))
drawtext (100,136,"MouseWheel: "+str(mousewheel))
if mousebutton = 1 then showmouse
if mousebutton = 2 then hidemouse
sync
until keystate (KEY_ESC) = true
end
' mousetest
KEY_ESC = 59
screen (640,480,"Mousetest")
hidemouse
do
cls
xm=str (mouseX)
drawtext (100,100,"MouseX: ")
drawtext (160,100,xm)
if mousebutton = 1 then showmouse
if mousebutton = 2 then hidemouse
sync
until keystate (KEY_ESC) = true
end
xm="320"
then there's no memory leak. So it seems to me that there is a problem with the str() function...?' mousetest
KEY_ESC = 59
screen (640,480,"Mousetest")
hidemouse
do
cls
xm=str (mouseX) 'instead of mousex I can also use a number but the result is still the same: memory leak
sync
until keystate (KEY_ESC) = true
end
miter=128
zm=120
time1=ticks()
for y=0 to 479
for x=0 to 639
zx=0
zy=0
cx= (x-320)/zm
cy= (y-240)/zm
i = miter
while (zx*zx+zy*zy <4) and (i >0)
tmp = zx * zx - zy * zy + cx
zy = 2 * zx * zy + cy
zx = tmp
i=i-1
wend
next
next
time2=ticks()
time=(time2-time1)/1000
print time, " seconds.";
input
John, that sounds so attractive that I can't refuse to read the source code of SB.
Hi Markus,Yes, I don't use a memory pool, this looked too complicated for a C beignner ... maybe I can use your implementation of shell/main.c?
The mandelbrot sample code came along with AllegroBASIC takes ~63 seconds on my i7 PC. Then I modified the code by commenting all graphics related lines, it costs almost the same duration. After that I tried to port it to a MY-BASIC shell version without graphics as well, it takes only ~15 seconds. I guess you were not using the memory pool, I recommend you to add a pool to optimize the memory performance of small chucks, since a simple implementation can even improve it more than 4 times faster. You can search for _open_mem_pool, mb_set_memory_manager(_pop_mem, _push_mem), _close_mem_pool() in shell/main.c to find my implementation.
MY-BASIC shell version without graphics:Code: [Select]miter=128
zm=120
time1=ticks()
for y=0 to 479
for x=0 to 639
zx=0
zy=0
cx= (x-320)/zm
cy= (y-240)/zm
i = miter
while (zx*zx+zy*zy <4) and (i >0)
tmp = zx * zx - zy * zy + cx
zy = 2 * zx * zy + cy
zx = tmp
i=i-1
wend
next
next
time2=ticks()
time=(time2-time1)/1000
print time, " seconds.";
input
tcc: error: undefined symbol 'MB_SIZEOF_LST'
tcc: error: undefined symbol 'MB_SIZEOF_DCT'
Yes, I don't use a memory pool, this looked too complicated for a C beignner ...
The forum has syntax highlighting for most of the popular languages. Just use a [code=c] for syntax highlighting. (see change to your above example)
@Markus, I simplified it by modifying the constant part:Code: C
/* ** {======================================================== ** Memory manipulation */ static const size_t _SIZEOF_4BYTES = 4; static const size_t _SIZEOF_8BYTES = 8; static const size_t _SIZEOF_32BYTES = 32; static const size_t _SIZEOF_64BYTES = 64; static const size_t _SIZEOF_128BYTES = 128; static const size_t _SIZEOF_256BYTES = 256; static const size_t _SIZEOF_512BYTES = 512; typedef unsigned _pool_chunk_size_t; typedef union _pool_tag_t { _pool_chunk_size_t size; void* ptr; } _pool_tag_t; typedef struct _pool_t { size_t size; char* stack; } _pool_t; static int pool_count = 0; static _pool_t* pool = 0; static long alloc_count = 0; static long alloc_bytes = 0; static long in_pool_count = 0; static long in_pool_bytes = 0; static long _POOL_THRESHOLD_COUNT = 0; static long _POOL_THRESHOLD_BYTES = 1024 * 1024 * 32; #define _POOL_NODE_ALLOC(size) (((char*)malloc(sizeof(_pool_tag_t) + size)) + sizeof(_pool_tag_t)) #define _POOL_NODE_PTR(s) (s - sizeof(_pool_tag_t)) #define _POOL_NODE_NEXT(s) (*((void**)(s - sizeof(_pool_tag_t)))) #define _POOL_NODE_SIZE(s) (*((_pool_chunk_size_t*)(s - sizeof(_pool_tag_t)))) #define _POOL_NODE_FREE(s) do { free(_POOL_NODE_PTR(s)); } while(0) static int _cmp_size_t(const void* l, const void* r) { size_t* pl = (size_t*)l; size_t* pr = (size_t*)r; if(*pl > *pr) return 1; else if(*pl < *pr) return -1; else return 0; } static void _tidy_mem_pool(bool_t force) { int i = 0; char* s = 0; if(!force) { if(_POOL_THRESHOLD_COUNT > 0 && in_pool_count < _POOL_THRESHOLD_COUNT) return; if(_POOL_THRESHOLD_BYTES > 0 && in_pool_bytes < _POOL_THRESHOLD_BYTES) return; } if(!pool_count) return; for(i = 0; i < pool_count; i++) { while((s = pool[i].stack)) { pool[i].stack = (char*)_POOL_NODE_NEXT(s); _POOL_NODE_FREE(s); } } in_pool_count = 0; in_pool_bytes = 0; } static void _open_mem_pool(void) { #define N 7 size_t szs[N]; size_t lst[N]; int i = 0; int j = 0; size_t s = 0; pool_count = 0; szs[i++] = _SIZEOF_4BYTES; szs[i++] = _SIZEOF_8BYTES; szs[i++] = _SIZEOF_32BYTES; szs[i++] = _SIZEOF_64BYTES; szs[i++] = _SIZEOF_128BYTES; szs[i++] = _SIZEOF_256BYTES; szs[i++] = _SIZEOF_512BYTES; mb_assert(i == N); /* Find all unduplicated sizes */ for(i = 0; i < N; i++) { s = szs[i]; for(j = 0; j < N; j++) { if(!lst[j]) { lst[j] = s; pool_count++; break; } else if(lst[j] == s) { break; } } } for(i = 0; i < pool_count; i++) { pool[i].size = lst[i]; pool[i].stack = 0; } #undef N } static void _close_mem_pool(void) { int i = 0; char* s = 0; if(!pool_count) return; for(i = 0; i < pool_count; i++) { while((s = pool[i].stack)) { pool[i].stack = (char*)_POOL_NODE_NEXT(s); _POOL_NODE_FREE(s); } } pool = 0; pool_count = 0; } static char* _pop_mem(unsigned s) { int i = 0; _pool_t* pl = 0; char* result = 0; ++alloc_count; alloc_bytes += s; if(pool_count) { for(i = 0; i < pool_count; i++) { pl = &pool[i]; if(s <= pl->size) { if(pl->stack) { in_pool_count--; in_pool_bytes -= (long)(_pool_chunk_size_t)s; /* Pop from stack */ result = pl->stack; pl->stack = (char*)_POOL_NODE_NEXT(result); _POOL_NODE_SIZE(result) = (_pool_chunk_size_t)s; return result; } else { /* Create a new node */ result = _POOL_NODE_ALLOC(pl->size); if((intptr_t)result == sizeof(_pool_tag_t)) { result = 0; } else { _POOL_NODE_SIZE(result) = (_pool_chunk_size_t)s; } return result; } } } } /* Allocate directly */ result = _POOL_NODE_ALLOC(s); if((intptr_t)result == sizeof(_pool_tag_t)) { result = 0; } else { _POOL_NODE_SIZE(result) = (_pool_chunk_size_t)s; } return result; } static void _push_mem(char* p) { int i = 0; _pool_t* pl = 0; if(--alloc_count < 0) { mb_assert(0 && "Multiple free."); } alloc_bytes -= _POOL_NODE_SIZE(p); if(pool_count) { for(i = 0; i < pool_count; i++) { pl = &pool[i]; if(_POOL_NODE_SIZE(p) <= pl->size) { in_pool_count++; in_pool_bytes += _POOL_NODE_SIZE(p); /* Push to stack */ _POOL_NODE_NEXT(p) = pl->stack; pl->stack = p; _tidy_mem_pool(false); return; } } } /* Free directly */ _POOL_NODE_FREE(p); } /* ========================================================} */
@John, But contexts are totally different from different users with C/C++, thus there's no one-fits-all memory pool solution, that's why C/C++ libs often accept customized memory allocator.
...
do
cls
x(i)=mousex
y(i)=mousey
gosub draw
i=i+1
if i>=1000 then i=i-1000
sync
until keypressed=true
end
draw:
...
return
Error: Line 23, Column 5: Wrong function reached in file _core_untilAny idea? Until I compiled it with the new sources it worked fine.
;)
I've fixed the EXIT bug with multiple line IF.
if zx*zx + zy*zy > 4 then col = c: exit
This only works with the older my-basic files. If I change the line intoif zx*zx + zy*zy > 4 then
col = c
exit
endif
it even does not work with that older revision.
DECLARE SUB mb_init ALIAS "mbas_init" LIB "mb"
DECLARE SUB mb_dispose ALIAS "mbas_dispose" LIB "mb"
DECLARE SUB mb_open ALIAS "mbas_open" LIB "mb"
DECLARE SUB mb_close ALIAS "mbas_close" LIB "mb"
DECLARE SUB mb_load_str ALIAS "mbas_load_str" LIB "mb"
DECLARE SUB mb_run ALIAS "mbas_run" LIB "mb"
mb_code = """
x = 10 : y = 2 : z = 30
IF x = 1 THEN PRINT "One"; : GOTO Done
IF y = 2 THEN PRINT "Two"; : GOTO Done
IF z = 3 THEN PRINT "Three"; : GOTO Done
Done:
END
"""
mb_init()
mb_open()
mb_load_str(mb_code)
mb_run()
mb_close()
mb_dispose()
Markus, please check the latest revision.Yes, thanks it works now.
if windowclosed = true then
end
endif
However, any other function (e.g. exit) is exceuted ...
If I check if the window was closed MY-BASIC now doesn't end the program anymore.
if (windowclosehandler!=0) {
windowclosehandler=1;
}
do
'... other code
until (keystate (KEY_ESC) = true) or (windowclosed=true)
dim x(2,2)=((1,1),(2,2))
Apart from that a DATA statement would be nice ...
Does that work with string lists?
if windowclosed = true then end
Is it possible to convert lists to 2-dimensional arrays?
I noticed you added a reset argument to mb_load_str.
I'm not sure how the game is suppose to work as I'm not a gamer. Q doesn't seem to quit.
I forgot to mention pressing enter after chosen a command.
Not working and unpredictable and it maxes out my CPU(s).
But one odd thing is MB is single threaded, how could it burn both of your CPU cores to 100%...
It does have a flexible IF that works just as well. Actually better as it doesn't have the traditional CASE compare / range / type restrictions.
does SB support separating a single statement into multi-lines?
Finally, I added Unicode token support to MY-BASIC! For instance I can use Chinese variable now:Code: Text
变量 = 22 另一个变量 = 7 print 变量 / 另一个变量;