Coder Social home page Coder Social logo

paladin-t / my_basic Goto Github PK

View Code? Open in Web Editor NEW
487.0 53.0 115.0 36.56 MB

A lightweight BASIC interpreter written in standard C in dual files. Aims to be embeddable, extendable and portable.

Home Page: http://paladin-t.github.io/my_basic/

License: MIT License

C 98.91% Batchfile 0.09% Makefile 0.24% HTML 0.76%
programming-language scripting-language interpreter basic

my_basic's Introduction

 _____ __ __     _____ _____ _____ _____ _____ 
|     |  |  |___| __  |  _  |   __|     |     |
| | | |_   _|___| __ -|     |__   |-   -|   --|
|_|_|_| |_|     |_____|__|__|_____|_____|_____|

Copyright (C) 2011 - 2024 Tony Wang

Build status MIT license

Web playground

Contents

Introduction

MY-BASIC is a lightweight BASIC interpreter written in standard C in dual files. It aims to be embeddable, extendable and portable. It is a dynamic typed programming language, reserves structured syntax, supports a style of prototype-based programming (OOP), also implements a functional paradigm by lambda abstraction. The core is written in a C source file and an associated header file. It's easy to either use it as a standalone interpreter or embed it with existing projects in C, C++, Java, Objective-C, Swift, C#, etc. and totally customizable by adding your own scripting interface.

Main features

MY-BASIC offers a wide range of features including:

  • Written in standard C, source code is portable to a dozen of platforms
  • Lightweight (within less than 128KB footprint), fast, and configurable
  • With both retro and modern BASIC syntax
  • Case-insensitive tokenization, and many other indelible BASIC flavour
  • Unicode support
  • Prototype-based programming, with reflection support
  • Lambda abstraction enhanced functional programming
  • Customizable referenced/non-referenced usertype
  • Collection construction and manipulation functions for LIST and DICT
  • Automatic releasing for referenced values (prototype, lambda, referenced usertype, list, dictionary, etc.) benefited from reference counting and garbage collection
  • Common numeric and string functions
  • Structured sub routine definition with the DEF/ENDDEF statements
  • Structured IF/THEN/ELSEIF/ELSE/ENDIF
  • Structured FOR/TO/STEP/NEXT, FOR/IN/NEXT, WHILE/WEND, DO/UNTIL
  • Reserved retro GOTO, GOSUB/RETURN
  • Importing multiple source files with the IMPORT statement
  • Debug API
  • Customizable memory pool
  • Easy API, for extending new BASIC functions
  • Easy interacting BASIC facilities at native side, and vice versa
  • More features under development

BASIC8

Get BASIC8 - the Fantasy Computer powered by MY-BASIC - on Steam for game and other program development in an integrated environment.

See awesome user creations.

BASIC at a glance

A "Hello World" convention in MY-BASIC:

input "What is your name: ", n$

def greeting(a, b)
	return a + " " + b + " by " + n$ + "."
enddef

print greeting("Hello", "world");

Read the MY-BASIC Quick Reference to get details about how to program in MY-BASIC.

Installation

Using standalone interpreter binary

This repository contains precompiled binaries for Windows, macOS and Linux, the easiest way is to download to get a direct playground. Or you can make a build by:

  • Using the Visual Studio solution my_basic.sln for Windows build
  • Using the Xcode workspace my_basic_mac.xcodeproj for macOS build
  • Using the makefile for Linux build

Follow these steps to compile an interpreter binary manually for other platform:

  1. Retrieve everything under the core and shell folders for a minimum setup
  2. Setup your toolchain for compiling and linking
  3. Compile core/my_basic.c and shell/main.c, while both includes core/my_basic.h; then link up an executable

The standalone interpreter supports three running modes:

  • Execute the binary without arguments to use the interactive mode
    • Type "HELP" and hint Enter to see usages
  • Pass a file to the binary to load and run that BASIC source code
  • Pass an argument -e followed with an expression to evaluate and print instantly as a simple calculator, eg. -e "22 / 7"

Combining with existing projects

Just copy core/my_basic.c and core/my_basic.h to your project and add them to the build pipeline. You can link with MY-BASIC as a lib as well.

For details about using MY-BASIC after integration, see MY-BASIC Quick Reference and read the Wiki pages.

MY-BASIC's workflow diagram can be concluded in a single image.

A simple setup:

#include "my_basic.h"

int main() {
	struct mb_interpreter_t* bas = NULL;

	mb_init();
	mb_open(&bas);
	mb_load_string(bas, "print 22 / 7;", true);
	mb_run(bas, true);
	mb_close(&bas);
	mb_dispose();

	return 0;
}

The manual explains most of the fundamental topics, however it doesn't cover everything; read the Wiki for supplements, like machinism behind MY-BASIC, efficient practice, etc:

Donate

List of donors.

Consider supporting MY-BASIC development with a donation if you like this project.

One-off donation via PayPal.

my_basic's People

Contributors

iultimatelp avatar paladin-t avatar szsam avatar unwiredben avatar wangrenxin avatar wwiv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

my_basic's Issues

Feature Request: Support for numbers at the beggining of a line

The code compiles without line numbers but when I add them, it comes up with an error
I wish to be able to use these in My BASIC, an example of this is:

10 PRINT "Hello World"
20 PRINT "This is My BASIC"

But that will be an error, so I have to do:

PRINT "Hello World"
PRINT "This is My BASIC"

I'm used to using these, so please add support for these.

Call a DEF purely from C

Hi paladin-t!

I loaded a BASIC script with some variable initializations and subrouting "run" into the interpreter. All this is running on a small Arduino board and I want to call the "run" subroutine from the main C loop.

The problem is, mb_eval_routine needs the pointer to void** (the AST?) to be called. At this stage I don't have this information, as the call is initiated from outside, not within the BASIC script. And in the documentation I do not find an information how to do so.

Here is where I am stuck:

int BasicScript::callRun() {
mb_value_t routine;
mb_value_t args[1];

mb_get_routine(bas, l, "RUN", &routine);
return mb_eval_routine(bas, l, routine, args, 0, NULL);   

}

Modify "+" operator to automatically do STR conversions?

Hey!

I figured it would be cool to have the "+" operator in _core_add automatically do string conversions if one of the parameters is a string, so it could handle this: "abc" + 3 like "abc" + STR(3) automatically.

I copied some code out of _std_str into _core_add and tried to hack it together and had a little bit of success, but I suppose my way is not the best, so if you have a spare hour, I'm sure you'd do it much better than my hack :)

Cheers!

Passing a struct

I have this struct:

typedef struct SpriteSheet {
    Buffer **sprites;
    int rows, cols;
    int width, height;
} SpriteSheet;

And my library passes it around by value, like this:

void nasl_draw_text(Buffer *b, SpriteSheet ascii, int x, int y, const char *fmt, ...);

Since it is not a reference nor a pointer, how do I instruct MY-BASIC to handle it?

String matching

I have added a "string in string" FIND command to my recent download of my_basic which takes a variable number of parameters ie FIND( sourcestring, searchforstring) or FIND( sourcestring, searchforstring, (int) startfromindex) . Although this was trivial I wonder if I could post it for inclusion?

I am new to GitHub so forgive me if this is an inappropriate question.
Regards,
Tony

Question on import module.

Hello.

I've been trying to embed your my_basic into an existing C++ application, and most things are going very well. Thank you!!

I have a question on imports. When using import "@modulename", it seems to only work right when the case matches the modulename. However the case doesn't matter when specifying the full name.

Example.

I'm registering a method like this. (FOO.TEST)

  mb_begin_module(bas, "FOO");

  mb_register_func(bas, "TEST", [](struct mb_interpreter_t* bas, void** l) -> int {
    mb_check(mb_attempt_open_bracket(bas, l));
    mb_check(mb_attempt_close_bracket(bas, l));
    std::cout << "[foo]\r\n";
    return MB_FUNC_OK;
  });

...

Now I can do this in my script and it works:

import "@TEST"

TEST.foo()
test.foo()
foo()

however this doesn't work:

import "@test"
foo()

Is this expected?

Projects using MY-BASIC

I am using MY-BASIC in my nasl project - and I love how light-weight and practical it is - great work! 😃

If you want to add scripting to your project, why not use a language that is BASIC ?
Much better than JavaScript, and other popular scripting languages, even Lua!

Are there other people using MY-BASIC ?
If so, then I would like a Wiki page dedicated to MY-BASIC projects. :)

Thanks for developing MY-BASIC 👍

Bug

Hello Wang,

I have notice a bug, interleaving conditions doen't works.
Example :

int _tmain(int argc, _TCHAR* argv[])
{
int result = MB_FUNC_OK;
mb_init();

char* buf1 = "IF FALSE THEN";
char* buf2 = "IF 1 THEN";
char* buf3 = "ENDIF";
char* buf4 = "PRINT 1";
char* buf5 = "ENDIF";

struct mb_interpreter_t* bas;
mb_open(&bas);

mb_reg_fun(bas,maximum);


mb_load_string(bas,buf1);
mb_load_string(bas,buf2);
mb_load_string(bas,buf3);
mb_load_string(bas,buf4);
mb_load_string(bas,buf5);

result = mb_run(bas);

mb_close(&bas);
mb_dispose();

return 0;

}

This example return 1

Regards,
Julien

IF语句的bug

IF语句的条件不成立时,如果下面没有ELSE语句的话,会出现bug,比如
i = 1
if i>1 Then
i = 2
endif
print i
就无法执行,但是加上ELSE语句就可以,如下所示
i = 1
if i>1 Then
i = 2
else
i = 3
endif
print i

Custom function

Hello,

I am at a loss to understand how i can define a custom NON-STATIC function in my cpp code.

exemple :
int _customFunc(struct mb_interpreter_t* s, void** l) { ... }

register:
mb_register_func(bas, "customfunction", _customFunc);
==> this call cannot work without the "Static" prefix before "_customFunc"

Can you help me on this please?

Thanks :)

Julien

Wrong function reached error on if-else-endif nest

Hello,
with the latest build, I run the if-else-endif program with error. It was able to run on older build. Since it was able to run on older build, I wonder if there is any changes on syntax of if-then-else-endif.

Copy of screen attached:

MY-BASIC Interpreter Shell - 1.2
Copyright (C) 2011 - 2017 Wang Renxin. All Rights Reserved.
For more information, see https://github.com/paladin-t/my_basic/.
Input HELP and hint enter to view help information.
] if a = 0 then
] if b = 0 then
] print "Start";
] endif
] else
] print "A"
] endif
]
]run
Start
Error:
Ln 5, Col 8 in Func: _core_else
Code 58, Abort Code 3
Message: Wrong function reached.

]

Thanks!

Fuzzed crashes and hangs

Using afl-fuzz I managed to generate input that crashes or hangs the interpreter. The zip file contains two directories, hangs/ and crashes/ containing the cases that make it hang or crash, respectively.

crashes and hangs.zip

Hope this helps!

Reset script only; Reenterable call stack

Hello,

first, thanks for this code!

I have a question
I would like to do a mb_reset() on script only, i.e i want to reset the script only,with the objective to use all variables and local functions with an other script.

In other words, i'm looking for a kind of mb_reset_script() function ...

Can you please help me on this point ?

Regards
Julien

DEF/ENDDEF and GOTO?

The quick reference document explicitly prohibits mixing DEF/ENDDEF with GOSUB/RETURN, but later, when GOTO is described there is no mention of that restriction. To us, this implies that we should be able to use GOTO in a program that also contains a structured subroutine, like this:

def MyFunc( item )
  result = 0
  if item = 5 then
    result = 1
  end if
  return result
enddef
'[more code]
if 0 = MyFunc(3) then
  goto NotFive
end if
' [more code]
NotFive:
'[more code]

However, we are getting an error on the GOTO about mixing instructional and structured subroutines, despite our belief that we are using only the structured subroutine.

So... Is this working as expected?

  • If so, it might be good to update to the quick reference to reflect the behavior.
  • If not, then is there any chance it might get fixed?

Set/Retrieve value in BAS from native application.

I found few helper functions, but there's no documentation on the arguments they intake.
Therefore i few questions.

  1. How can i set a 'test=2' value or pass value from native C application to the BAS ?
  2. How can i retrieve the value of 'test' to process in native application after the BAS is executed ?
 struct mb_interpreter_t* bas = NULL;
  mb_init();
  mb_open(&bas);
  if (mb_load_string(bas, "test = 1+2+3; print test", true) == MB_FUNC_OK)
  {
    int iResult = mb_run(bas, true);

    mb_value_t val0;
    void **l = NULL;
    int iRes = mb_get_value_by_name(bas,l,"test",&val0);
    printf("VALU:%i RES:%i\n", val0.value.integer,iRes); 
  }
  else
    printf("Failed\n");

6
VALU:0 RES:0

  1. What are the arguments voidl** in the following functions ?

MBAPI int mb_get_value_by_name(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t* val);
MBAPI int mb_add_var(struct mb_interpreter_t* s, void** l, const char* n, mb_value_t val, bool_t force);
MBAPI int mb_get_var(struct mb_interpreter_t* s, void** l, void** v, bool_t redir);
MBAPI int mb_get_var_name(struct mb_interpreter_t* s, void* v, char** n);
MBAPI int mb_get_var_value(struct mb_interpreter_t* s, void* v, mb_value_t* val);
MBAPI int mb_set_var_value(struct mb_interpreter_t* s, void* v, mb_value_t val);

interpreter crash with unmatched if - endif

Hi,
Run the following code and you'll get an exception error. The interpreter should stop and generate some sort of error message (unmatched if-endif?) but instead, it crashes. Any idea?

a=3
if a <> 3 then
print "a<>3";
else
a=10
if a >= 7 and a < 19 then
print "we're in "
if (a mod 2) = 0 then
print "0";
else
print "1";
endif
else
print "we're out ";
endif

Generic Progamming Support.

Like From C++&D-Lang Template.
generic function

generic add(A,B)
return A + B 
genericend

print add(1,2)
print add("abc","def")

generic class

generic class(class T)
obj = T
genericend

tempint = obj(1)
temphello = obj("hello world")

print tempint
print temphello

Sample factrical(generic)

generic fact(num)
if num = 1 then
return 1
else 
return fact(num-1)*num
endif
genericend

print fact(10) REM =3628800

Support plz.

tests, bits and endianness

how i can:
1- run a self-tests routines?
2- official suport to 16, 32 and 64-bit ?
3- this is endianess safe? (little and big-endian cpus)

this very impressive ! congratulations!

Manual "next-line" trigger?

Hey, I am integrating this in a game of mine where the players can program robots to execute tasks. Imagine the following the scenario:

WALK "fwd"
TURN

TURN should execute after WALK is finished, so I need some sort of manual trigger to tell my_basic to resume the code executions. Is something like that possible? Thanks!

Command prompt mode

How can I implement a "command prompt mode" for My Basic? This would be similar to the Python command mode, where it's possible to type in commands and have them execute immediately. Data is retained in memory but commands are not saved to a listing.

Example:

> a$="hello"
> print a$;
hello
> b$="world"
> print a$," ",b$;
hello world

Right now, it seems like I can use mb_load_string to run a command but then I have to use mb_reset after that, to remove the previous command. Of course, that also clears out the data.

Error and exception handling

Great job, Renxin. Very neat and lightweight Basic interpreter.
I wonder if it is possible to support VB syntax like On Error Statement and other keywords etc. ?

Thanks,
niucool

Eval a line of code without resetting the interpreter?

So I was writing some bindings to control Arduino functions with this, and thought it would be really cool if you could do something suspending a running interpreter, evaluating a line of code, and then returning to normal execution.

This would let you interact with a running program during development, change variables, etc, and would be great for using it like the early home computers that you used through a BASIC prompt.

Is this possible with the current API?

Infinite loop

My registered C function enter an infinite loop.
This is my code:

static int _salir(struct mb_interpreter_t* s, void** l)
{
	int result = MB_FUNC_OK;
	mb_assert(s && l);
	Psalir = true;  /*do something over and over again*/
	return(MB_FUNC_OK); /*won't exit, entered a inifinite loop */
}

void Bfile(const char *m)
{
	mb_init();
	mb_open(&bas);
	mb_register_func(bas, "SALIR", _salir);
	mb_load_file(bas, m);
	mb_run(bas, true);
	mb_close(&bas);
	mb_dispose();
}

The only solution that has worked for me has been this:

static int _salir(struct mb_interpreter_t* s, void** l)
{
	int result = MB_FUNC_OK;
	mb_assert(s && l);
	Psalir = true;
        mb_close(&bas) /* added to force an exit */;
	mb_dispose();   /*added to force and exit*/
	return(MB_FUNC_OK); 
}

void Bfile(const char *m)
{
	mb_init();
	mb_open(&bas);
	mb_register_func(bas, "SALIR", _salir);
	mb_load_file(bas, m);
	mb_run(bas, true);
	mb_close(&bas);
	mb_dispose();
}

Suspending inside a FOR-Loop breaks the loop

Hi, I am implementing a simple WAIT function which waits a few seconds (non-blocking since I do it inside Unreal Engine 4), and it works great with mb_schedule_suspend(s, MB_FUNC_SUSPEND) and mb_run(s, false);
However I stumbled across a bug, suspending inside a FOR-Loop will not resume when calling mb_run. Here is my implementation of WAIT:

int wait(struct mb_interpreter_t* s, void** l)
{
	// Will return OK
	int result = MB_FUNC_OK;

	// Holds the delay to wait (in milliseconds)
	int delay = 0;

	// Needed otherwise we can't return values!
	mb_check(mb_attempt_func_begin(s, l));
	mb_check(mb_attempt_func_end(s, l));

	// Check if an argument was passed
	if (mb_has_arg(s, l))
	{
		// Try to read an int argument into &delay
		mb_check(mb_pop_int(s, l, &delay));
	}

	// Suspend the BASIC execution until we start it again using mb_run
	mb_schedule_suspend(s, MB_FUNC_SUSPEND);
	UE_LOG(LogTemp, Log, TEXT("Suspended"));

	// Set up a timer to wait for the specified time
	float DelayTime = delay / 1000.f;
	FTimerHandle ResumeTimer;
	BasicWorldRef->GetTimerManager().SetTimer(ResumeTimer, [=]() {
		// After the UE4 timer triggered, call mb_run to resume the execution where it left of
		UE_LOG(LogTemp, Log, TEXT("Resumed"));
		mb_run(s, false);
	}, DelayTime, false);

	return result;
}

And here's my BASIC code to test with:

PRINT "Waiting in a loop"
FOR a=1 TO 5
  PRINT "In the loop!",a
  WAIT 1000
  NEXT a

PRINT "Finished"

It is printing the first "In the loop!" and "1", but then nothing happens, so it won't reach the next iteration (probably NEXT lost the reference to the for loop?)

Is there a way to have nested dictionaries?

Something like:

a=dict()
a(1)=dict()

a(1)(1)="test"

In Lua or Python it is possible. Is it possible in my_basic? The above syntax doesn't work (I know it can be done with GET and SET, but I wondered if there was a more readable way to do it)

I really like this project, for its extreme compactness, and for how much it can achieve with such a small size

Clearer error handling for assigning reserved keywords

Hey! I found something today. Running this code:

LET val = 3

returns an error. I searched a bit why it error as this code is fine, but then I found out why: because "val" is a registered keyword. The error handling isn't clear in this situation, it would be great if the returned error would be "Cannot assign registered keyword" or something.

Thanks!

Bug with "-" and "space" character

Hi,

When my basic is as following, i get an error :
strike =3000
variable1= strike-customfunction()

But when i get a space between strike and customfunction() that's work :
strike =3000
variable1= strike -customfunction()

Regards,
Julien

MY-BASIC Embedded Applications for the Awesome List

I maintain an embedded Linux framework called "MuntsOS Embedded Linux" for Raspberry Pi and BeagleBone boards. A potential user recently asked about running a Basic interpreter on MuntsOS and while doing some searching to answer that question, I ran across MY-BASIC.
I have now created a MY-BASIC extension package for MuntsOS that includes compiled-in support for Linux kernel A/D inputs, GPIO pins, and PWM outputs, using the "Linux Simple I/O Library", with more kinds of I/O to follow.

I've also built some MY-BASIC Debian packages for systems running Debian 9 (Stretch), including the BeagleBone and the Raspberry Pi.

Both the Linux Simple I/O Library and the MuntsOS Embedded Linux repositories now contain Basic test programs for MY-BASIC.

Linux Simple I/O Library: http://git.munts.com/libsimpleio
MuntsOS Embedded Linux: http://git.munts.com/arm-linux-mcu
Debian Package Repository: http://repo.munts.com/debian9

Please add these URL's to the Awesome list embedded section.

Dict item not printed

When a var is defined as a dict() in a class, printing a value from it can print the variable type followed by an error. Here's some sample code:

class request
    var headers = dict()
    var cookies = dict()

    def sendheaders(s)
        print get(headers, s) + chr(10)
    enddef

    def sendbody(s)
    enddef

    def sendstatus(s)
    enddef

endclass

d = dict()
d("testing") = "123"
print "1: " + d("testing") + chr(10)
print "2: " + get(d, "testing") + chr(10)
print d("testing") + chr(10)

req = new(request)
req.headers("testing") = "123"

h = req.headers

print "3: " + h("testing") + chr(10)
print "4: " + get(h, "testing") + chr(10)
print h("testing") + chr(10)
print "5: " + req.headers("testing") + chr(10)
print "6: " + get(req.headers, "testing") + chr(10)

' This fails with:
'
' DICT
' Error:
'     Ln 34, Col 17
'     Code 30, Abort Code 3
'     Message: Comma or semicolon expected.
print req.headers("testing") + chr(10)

Running this produces:

1: 123
2: 123
123
3: 123
4: 123
123
5: 123
6: 123
DICT
Error:
    Ln 42, Col 17
    Code 30, Abort Code 3
    Message: Comma or semicolon expected.

Seperate arguments with spaces?

Hey, sorry for posting so many issues, but I'm trying to get the most out of this library!

Is there a way to seperate arguments to functions by spaces instead of commas too?
Like this:

MYFUNC 90 20 "arg3"

Instead of

MYFUNC 90, 20, "arg3"

I've looked into _is_separator_char and tried to a whitespace char there, but it did not work unfortunately. Any idea? Thanks!
Thanks!

Debug Handler always called with NULL source file name

I'm experimenting with the mb_debug_set_stepped_handler() function and I've noticed that the handler function is always called with a NULL (i.e. 0x00000000000000000) for the source_file parameter. While investigating, I've set breakpoints in several of my registered function and checked the content of the mb_interpreter_t struct that is passed around and the source_file member has always been NULL. Is there any way to get the actual source file name for the statement related to the debug step handler?

Porting to ESP8266 Arduino

Hi,
I'm porting my_basic to ESP8266 2.3.0 and Arduino 1.6.12. I found that there is an alignment error that causes system to hang. I guess pointer variables in structures must be aligned to dword. For example, the following structure, "bool_t valid;" is one byte so the following variables would be un-aligned and causes hang.

typedef struct mb_interpreter_t {
/** Fundamental /
bool_t valid;
void
userdata;
_ls_node_t* ast;

So I added three dummy "bool_t"s to align variables. Then it worked fine.

typedef struct mb_interpreter_t {
/** Fundamental /
bool_t valid;
bool_t dummy1;
bool_t dummy2;
bool_t dummy3;
void
userdata;
_ls_node_t* ast;

I think that it can be fixed by adding some compile switches to force align variables but I'm not familiar with those compiler switches. If you can address this issue and fix it for future release, that would be great.

Thanks!

There is a bug in STR

when i do this like "STR(2334)" ,it will fail . Do you have something to solve this ?

the error information as below:

Debug Assertion Failed!

Program: ...roject\Debug\my_basic.exe
File: f:\dd\vctools\crt\crtw32\misc\dbgheap.c
Line: 1322

Expression: _CrtIsValidHeapPointer(pUserData)

Documentation out of date

The Quick Reference and Wiki both appear to be referencing a different version of this package. For example, they refer to the function mb_reg_fun(struct mb_interpreter_t* s, mb_func_t *f) but no such function exists in the my_basic.c/.h available here. Other functions, like mb_check(), are referenced but never documented, though at least those appear to exist in the source.

Also, some explanations and/or better, more detailed examples of integrating with a C project and extended the language by adding custom functions & routines would be a HUGE help.

[EDIT: corrected typos, removed unnecessary example code bug]

STR() sometimes fails when using reals

Hey there, found another bug :)

Sometimes, when calling

PRINT "my float is = " + STR(3.1415)

it will output "my float is = 0". I debugged it, and it seems like the _std_str function thinks the value is a MB_DT_INT, and therefore reads the arg.value.integer value and returns it.

Input Touch events from my tablet screen

Hello, is it possible to implement the touch event from my tablet touchscreen, from my tablet in to touch basic like the "input" - command, or Is there an command already implemented, and if, what is its name, and how can I find it?

Thanks a lot for give me the possibility to asc about this

Get the name of a BASIC function inside it's C++ definition?

Hey,

when implementing BASIC function in C++ using mb_register_func(), is there a way to retrieve the name of that function? I need that since I'm building a dynamic handler (multiple functions are registered to the same callback, and the callback needs to decide which function invoked it).

I tried to pop a string from the stack, but that resulted in an infinite loop.

Help is greatly appreciated :) Cheers, Johnny

Errors with a list of objects

I experimented with lists of object instances:

' Define an object class

class Object
  var myadjective = "UNINITIALIZED"

  def Describe(s)
    myadjective = s
  enddef

  def Write()
    print "I'm an ", myadjective, " object!";
  enddef
endclass

print "Object List Test";;

' Create a list of object instances

Obj1 = new(Object)
Obj1.Describe("awesome")

Obj2 = new(Object)
Obj2.Describe("ugly")

ObjectList1 = List(Obj1, Obj2)

Obj1 = Nil
Obj2 = Nil

for X in ObjectList1
  X.Write()
next

' Create another list of object instances

Obj3 = new(Object)
Obj3.Describe("unfathomable")

Obj4 = new(Object)
Obj4.Describe("ordinary")

ObjectList2 = List(Obj3, new(Object))

Obj3 = Nil
Obj4 = Nil

for X in ObjectList2
  X.Write()
next

' Try to create a third list of object instances

ObjectList3 = List(new(Object), new(Object))

Here is the output from running the program:

Object List Test

I'm an awesome object!
I'm an ugly object!
I'm an unfathomable object!
I'm an ordinary object!
Error:
    Ln 53, Col 35
    Code 28, Abort Code 3
    Message: Colon expected.

At line 42 it executes, but the second item in the list is Obj4, instead of an uninitialized fifth object instance.
At line 53 it fails.

any plans to ?

  • endianess support
  • multi-thread safe
  • network support
  • http client (sync or async)

Posative (with sign) exponents not supported in REAL constants

I believe that condition on line 5883 of my_basic.c should end with (c == '-' || c == '+') instead of just c == '-' when checking for an exponent sign. With the original code, a statement like

   x = 1.23E+07

produces an error. With the proposed change, the constant is correctly interpreted. I'm not familiar enough with the code to be certain that there are no unexpected effects though, so I'm suggesting the change this way.

[EDIT: I originally and incorrectly used negative, when I mean positive. Sorry.]

BASIC8 - A MY-BASIC Powered Fantasy Computer

Hello,

It's been a while since I made MY-BASIC open source. The interpreter itself has been keeping as compact as possible. It's very interesting to see how it's involved with your creativity, I cannot make these improvements without your voice. However, I've thinking about making something playable based on the kernel.

It will be an integrated software, in which user can write code in BASIC, make sprites, maps, and music; all of this will make up - a playable video game cartridge - a packed file, no plastic or circuit :). User can test it, improve it, then share it with a community. Of course a user can download and play games created by other users. All assets are readable and editable for all users, so users can learn from each other, and derive new cartridges. You'll be familiar with this concept if you've played PICO-8. But my design is different from PICO-8, some API will be improved, there will also be some API that PICO-8 doesn't offer, the GUI is a new design, and touching friendly for future mobile porting possibility.

The first release will come out later this year, if there's no unexpected event. It will be for Windows PC at first, but it won't be difficult to port to macOS, Linux, mobiles, RasPi, etc.

I'd like to know, if you are interested to this, what kind of features you want to see the most? For example:

  • Ideas about any API
  • Simple 3D graphics
  • Edit on mobile devices
  • Can create standalone executable player for PC
  • Can create standalone executable player for mobiles, and sellable to marketplaces
  • Play it in web browsers
  • Play it on a dedicated hardware
  • Supports collision detection, and or physics reaction
  • Supports LAN play
  • etc.

This issue will keep open until it's ready to go, then I'll make a dev log somewhere around instead of this. Feel free to leave a message below. Any suggestions are welcome, but I won't promise I'll implement them :)

Sincerely
Wang Renxin

Different syntax

I love this project. I would like to use it, but have a more C / JavaScript like syntax. Is there anyone interested in working on it with me?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.