berry-lang / berry Goto Github PK
View Code? Open in Web Editor NEWA ultra-lightweight embedded scripting language optimized for microcontrollers.
Home Page: https://berry-lang.github.io
License: MIT License
A ultra-lightweight embedded scripting language optimized for microcontrollers.
Home Page: https://berry-lang.github.io
License: MIT License
Would it be possible to add toupper(string)->string
and tolower(string)->string)
to the standard Berry library to transform to uppercase or lowercase?
I'm adding a native function, but this could be useful to others if it were included by default.
Thanks
First let me say that Berry is fantastic. I'm considering using Berry as a scripting language for Tasmota (https://github.com/arendst/Tasmota) running on ESP32. It's compact enough, powerful and easy to embed in existing code.
ESP8266 is too short in memory, but ESP32 makes a perfect target for the Berry language. I did a quick & dirty embeddeding Berry in Tasmota with no issue and it compiles fine. The documentation is very clear and easy to follow. Calling Berry functions from Tasmota, and the reverse works fine.
Now here are my questions:
Native modules: I tried to register native module used by import
at runtime but I have the feeling that it's currently not supported except for the pre-included libraries. Do you plan to allow custom libs?
Yield/Wait: it would be fantastic to be able to yield()
from within Berry code to give back control to the host code, and resume execution later. I understand that it's probably not straightforward, but this would make a great way to do async-style code that would not block the host code.
if i change list
on line 20 to lout
, i get a segfault:
Program received signal SIGSEGV, Segmentation fault.
0x000000000040aecc in i_getglobal (vm=0x7ffff7d6dee8, ins=1208221695)
at src/be_vm.c:276
276 *v = vm->global[idx];
(gdb) p idx
$1 = 262143
#0 0x000000000040aecc in i_getglobal (vm=0x7ffff7d6dee8, ins=1208221695)
at src/be_vm.c:276
#1 0x000000000040e30b in vm_exec (vm=0x7ffff7d6dee8) at src/be_vm.c:715
#2 0x000000000040e701 in do_closure (vm=0x7ffff7d6dee8, reg=0x624378, argc=0)
at src/be_vm.c:771
#3 0x000000000040e964 in be_dofunc (vm=0x7ffff7d6dee8, v=0x624378, argc=0)
at src/be_vm.c:804
#4 0x0000000000409ed6 in m_pcall (vm=0x7ffff7d6dee8, data=0x7fffffffe9e0)
at src/be_exec.c:96
#5 0x0000000000409d4f in be_execprotected (vm=0x7ffff7d6dee8,
f=0x409ea1 <m_pcall>, data=0x7fffffffe9e0) at src/be_exec.c:62
#6 0x0000000000409f5f in be_protectedcall (vm=0x7ffff7d6dee8, v=0x624378,
argc=0) at src/be_exec.c:108
#7 0x000000000041767b in be_pcall (vm=0x7ffff7d6dee8, argc=0)
at src/be_api.c:763
#8 0x000000000041979b in dofile (vm=0x7ffff7d6dee8) at default/berry.c:103
#9 0x0000000000419992 in analysis_args (vm=0x7ffff7d6dee8)
at default/berry.c:167
#10 0x0000000000419a52 in main (argc=2, argv=0x7fffffffeb58)
at default/berry.c:187
Is it possible to take a function off the stack inside an native function and put it back on the stack at a later time for execution to implement a callback?
try
undeclaratedvariable
except .. as e, v
print("error")
end
This is not work, it should return error
but it returns 'undeclaratedvariable' undeclared
. Why?
https://github.com/gztss/berry/blob/340e5384b473bf307f01b26fd34a5152c04a6e32/test/index.be#L28
In this file, adding this line of code will result in an error, which currently appears to be a VM bug.
Add more C-API like Lua.
1. What __iterator__
does?
2. Why isinstance
does not work?
>>> type(a)
instance
>>> isinstance(a)
false
3. What classof
does and issubclass
does?
4. Why this happens:
>>> n = 0
>>> type(n)
int
>>> type(n) == int
false
?
I think it should return true
, because n
is int
.
I know this is stupid question, but there is no english docs :(
I saw that berry has some predefined functions like: tostring and tobool (among others).
Right now berry allows for code like:
class base
def init()
end
def tostring()
# returning void is also considered okay
return 2 #results in segment fault for me
end
end
b = base();
print (b)
From my point of view this is not entirely correct so I'm suggesting a solution: doing type checking for predefined functions like those mentioned above.
Below https://github.com/gztss/berry/blob/master/src/be_strlib.c#L103 add this if statement :
// Don't forget to #include "be_debug.h" at the top of the file
if (top->type != BE_STRING) {
be_debug_error(vm, 1, "expected return type string in function 'tostring");
}
Something similar can be applied for the rest of predefined functions. Let me know what you think.
file.be:
def hi()
print("hi")
end
import:
> import file
> file.hi()
attribute_error: 'nil' value has no method 'hi'
stack traceback:
stdin:1: in function `main`
Berry: latest version.
OS: macOS Darwin x86_64
I didn't find any way to iterate on map keys, iter()
actually returns a iterator for values, not keys:
> m={"a":1,"b":2,"c":3}
> for i: m print(i) end
1
2
3
Did I miss something?
Thank you for shared this impressive project. Is there any porting guide to the stm32f103 mcu. I will be porting and test. Thanks!
I have an idea about namespace management.
Code:
import os
os.system("ls")
Code with namespace improvements:
import os
system("ls")
Hi @skiars ,
I will have a suggestion for the next release. These:
> var a = 10
> var a = 'hi'
> print(a)
hi
Enum, const variable, Recursion function. etc. should be added.
We should be able to use the code we wrote in the CLI interface. (For Windows)
./berry myfirstcode.be
We should be able to customize the command line:
Console.BackgroundColor = Color.red
(C#) like...
That's all I want to add for now. Thank you
a = 0xe123
print(a)
b = 0x1234
print(a)
is this supported or am I missing something ?
it prints 0
谢谢作者,辛苦了
@skiars after compiling Berry on Windows 10 I saw file named berry.lib, I delete it and nothing happened. What does this file do?
3 errors generated by 3 files
./build_map.h:31:37: error: a space is required between consecutive right angle brackets (use '> >')
std::vector<std::vector<str_info>> m_hashtable;
build_map.cpp:31:5: error: unknown type name 'constexpr'
constexpr int opif = 48;
hash_map.cpp:137:57: error: non-aggregate type 'const std::map<std::string, std::string>' (aka 'const map<basic_string<char, char_traits<char>, allocator<char>
>, basic_string<char, char_traits<char>, allocator<char> > >') cannot be initialized with an initializer list
const static std::map<std::string, std::string> tab = {
I have fixed those errors by modified 3 files:
1. tools/map_build/Makefile (added -std=c++11)
- @ g++ -O2 hash_map.cpp map_build.cpp main.cpp -o $(TARGET)
+ @ g++ -O2 -std=c++11 hash_map.cpp map_build.cpp main.cpp -o $(TARGET)
2. tools/str_build/Makefile (added -std=c++11)
- @ g++ -O2 main.cpp build_map.cpp -o $(TARGET)
+ @ g++ -O2 main.cpp build_map.cpp -std=c++11 -o $(TARGET)
3. tools/str_build/build_map.h (added spaces between <> )
- std::vector<std::vector<str_info>> m_hashtable;
+ std::vector< std::vector<str_info> > m_hashtable;
This is a greate job, thank you!
When I compiled Betty, reported an error:
lindx@lindx-PC:~/local/berry$ make
[Make] map_build
[Prebuild] generate resources
terminate called after throwing an instance of 'std::regex_error'
what(): Invalid range in bracket expression.
Makefile:59: recipe for target 'generate/be_const_strtab.h' failed
Will the network stack, file system and other hardware drivers be integrated later? This is what I care about.
Micropython还是其他的类似的。感觉都没有DEBUG的功能。
如果能具备电脑上IDE而目标设备上运行berry,能够在IDE上进行debug,例如下断电,监视变量什么的。
Hi,
I'm confused when using the following code:
// be_top == 0
be_loadstring(vm, "1+1");
// be_top == 1
// be_absindex(vm, 0) == 2
be_pcall(berry.vm, 0);
// be_top == 1
const char *s = be_tostring(berry.vm, 0);
// s == "2"
be_pop(vm, 1);
// be_top == 0
I thought index = 0
was forbidden yet this is the only way to run the code above. I'm confused.
The calls above seem to refer to arguments that are above the stack top and should be invalid?
https://github.com/gztss/berry/blob/340e5384b473bf307f01b26fd34a5152c04a6e32/src/be_vm.c#L450
https://github.com/gztss/berry/blob/340e5384b473bf307f01b26fd34a5152c04a6e32/src/be_vm.c#L682
The value pointed to by the variable v
may invalid when the stack is expanded.
There is a lot of code in the VM that doesn't consider the auto-expansion stack. Such as this code:
bvalue *v = &vm->top;
// some operation that causes stack expansion
var_setint(v, 45); // access to `v` may be invalid
When the stack expands, the entire stack will re-allocate memory, so the original pointers to elements in the stack will be invalidated. In earlier versions, Berry used a fixed-size stack, but the extensible stack caused bugs in some code.
In be_vm.c, functions like i_call
have such problems.
I think it is necessary to use an automated test to verify the interpreter. As an exploration, here is a simple automated test framework:
I just think the support of async
/await
can be divided into two steps:
1. First implement async/await with library functions;
2. Implement related syntactic sugar.
We should open a new issue.
Originally posted by @skiars in https://github.com/Skiars/berry/issues/65#issuecomment-669629602
Hi, I am trying to translate the statements into my language, but it gives me "syntax_error: stdin: 1: stray '\ 167' s program" error.
MY LEXER:
"NONE", "EOS", "ID", "INT", "REAL", "STR",
"=", "+=","-=", "=", "/=", "%=", "&=", "|=",
"^=", "<<=", ">>=", "+", "-", "", "/", "%",
"<", "<=", "==", "!=", ">", ">=", "&", "|",
"^", "<<", ">>", "..", "&&", "||", "!", "~",
"(", ")", "[", "]", "{", "}", ".", ",", ";",
":", "?", "->", "wenn", "swenn", "sonst", "während",
"zum", "funktion", "ende", "klasse", "brechen", "fortsetzen",
"rückkehr", "wahr", "falsch", "nil", "var", "machen",
"importieren", "wie", "versuchen", "außer", "erziehen"
The expression I use is:
klasse person
var name, age
funktion init(name, age)
self.name = name
self.age = age
ende
funktion tostring()
rückkehr 'name: ' + str(self.name) + ', age: ' + str(self.age)
ende
ende
I think the problem stems from this method. This method checks the English letters. How can I sort the letters that are not in the English alphabet?
static int is_letter(int c)
{
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c == '_');
}
steps: build berry .
run berry test\test.be
note results of operator tests
reload operator test: A(100) + A(20) = nil
reload operator test: A(100) > A(20) = nil
There should be a way of making this possible: ./berry folder/script.be argv1 argv2 hi
and from script.be
I should be able to do this: print (arg[1])
.
def a()
a1 = 42
print (a1)
end
# calling this won't issue an error
a
b = 2;
print (b);
The problem lies in file be_parser.c, function: suffix_expr
1- which compilers are supported?
2- works on 64 and 32-bits OS (targets)?
3- bytecode works across big and little endianess?
great job!
very impressive
Is it possible to compile to a bytecode file (similar to .luac file) ?
So that bytecode file can be taken and executed at another environment, where only minimal berry runtime is present, and no compiler available. That would be very useful on small and embedded systems, where there's no need to have source files in plaintext, and compiler is also not needed.
Looking at be_api.c file didn't help much.
Isn't code_dump
what I'm looking for?
When I read Berry's source code, I found a puzzle in be_map.c
static int eqnode(bmapnode *node, bvalue *key, uint32_t hash)
{
bmapkey *k = key(node);
if (hashcode(key(node)) == hash && (int)k->type == key->type) {
switch (key->type) {
case BE_NIL:
return 0;
case BE_BOOL:
return key->v.b == k->v.b;
case BE_INT:
return key->v.b == k->v.b;
case BE_REAL:
return key->v.r == k->v.r;
case BE_STRING:
return be_eqstr(key->v.s, k->v.s);
default:
return key->v.p == k->v.p;
}
}
return 0;
}
when case BE_INT, it is should be comparing int type, not bool. I don't know if I'm right ?
/* IMPORTANT: This must follow the enum found in be_lexer.h !!! */
static const char* const kwords_tab[] = {
"NONE", "EOS", "ID", "INT", "REAL", "STR",
"=", "+", "-", "*", "/", "%", "<", "<=",
"==", "!=", ">", ">=", "..", "<<", ">>", "^", "|", "&", "&&",
"||", "!", "~",
"(", ")", "[", "]", "{", "}", ".", ",", ";",
":", "if", "elif", "else", "while", "for",
"def", "end", "class", "break", "continue",
"return", "true", "false", "nil", "var", "do",
"import", "as", "require",
};
At first I didn't realize I must follow the pattern but then my tests started to fail and after an investigation I figured it out.
Edit 1: Once again, I cannot stress this enough but berry needs more tests (for each kind of operation) and documentation :D
Edit 2: Basically it needs a file which you can run before commiting new changes and if that test(which is composed of several tests) passes then you are sure you didn't break the language.
@skiars What is the super and real data types?
Major optimization objects:
Berry needs a keyword which enables it to use more than just one file programs. I added a such keyword here: http://tildesquad.ddns.net:3001/murii/berry/src/branch/master/src/be_parser.c#L1103
Maybe you'll find this interesting
Completing incremental garbage collection.
def aaaa()
return aaaa()
end
aaaa();
This code results in segment fault. I think this is due to hitting the limit of the stack size. If that's the case I think berry needs to issue an error.
Parse the following code
a = 1
b = 0
a = b (b) = 1
We expect to get an error message stating the third line (b) = 1
but the program will crash.
Is there any delay function in Berry like python time.sleep()
?
Implement file operation interface like this:
f = file("test.txt")
f.open()
f.write("Hello Berry\n")
f.close()
I was trying to add a new function, assert, in be_baselib.c but soon I came across an impairment and that is: the lack of getting the current line and file from bvm structure.
From what I understand reading the source code this is not possible. Please advise.
1. How to split line by char like in python?
python:
line = "Hello, world!"
print(line.split(" ")) # ['Hello,', 'world!']
2. How to trim \n
from input()
?
>>> a = input('> ')
> hi
>>> print(a)
hi
>>>
Sorry for this stupid question, but I can't find any english documentation about Berry.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.