diff --git a/lib/libesp32/Berry-0.1.10/library.properties b/lib/libesp32/Berry-0.1.10/library.properties deleted file mode 100644 index 23cdd9946..000000000 --- a/lib/libesp32/Berry-0.1.10/library.properties +++ /dev/null @@ -1,7 +0,0 @@ -name=Berry -version=0.1.10 -author=Guan Wenliang , -maintainer=Stephan Hadinger -sentence=Berry scripting language for Tasmota32 -paragraph=Berry is a ultra-lightweight dynamically typed embedded scripting language. -architectures=esp32 diff --git a/lib/libesp32/Berry-0.1.10/src/berry_conf.h b/lib/libesp32/Berry-0.1.10/src/berry_conf.h deleted file mode 100644 index f645c0338..000000000 --- a/lib/libesp32/Berry-0.1.10/src/berry_conf.h +++ /dev/null @@ -1 +0,0 @@ -#include "port/berry_conf.h" \ No newline at end of file diff --git a/lib/libesp32/Berry-0.1.10/LICENSE b/lib/libesp32/Berry/LICENSE similarity index 100% rename from lib/libesp32/Berry-0.1.10/LICENSE rename to lib/libesp32/Berry/LICENSE diff --git a/lib/libesp32/Berry/berry-logo.png b/lib/libesp32/Berry/berry-logo.png new file mode 100644 index 000000000..1eb419089 Binary files /dev/null and b/lib/libesp32/Berry/berry-logo.png differ diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_driverlib.c b/lib/libesp32/Berry/default/be_driverlib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_driverlib.c rename to lib/libesp32/Berry/default/be_driverlib.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_energylib.c b/lib/libesp32/Berry/default/be_energylib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_energylib.c rename to lib/libesp32/Berry/default/be_energylib.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_gpio_lib.c b/lib/libesp32/Berry/default/be_gpio_lib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_gpio_lib.c rename to lib/libesp32/Berry/default/be_gpio_lib.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_light_lib.c b/lib/libesp32/Berry/default/be_light_lib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_light_lib.c rename to lib/libesp32/Berry/default/be_light_lib.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_modtab.c b/lib/libesp32/Berry/default/be_modtab.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_modtab.c rename to lib/libesp32/Berry/default/be_modtab.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_port.cpp b/lib/libesp32/Berry/default/be_port.cpp similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_port.cpp rename to lib/libesp32/Berry/default/be_port.cpp diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_tasmotalib.c b/lib/libesp32/Berry/default/be_tasmotalib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_tasmotalib.c rename to lib/libesp32/Berry/default/be_tasmotalib.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_wirelib.c b/lib/libesp32/Berry/default/be_wirelib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/be_wirelib.c rename to lib/libesp32/Berry/default/be_wirelib.c diff --git a/lib/libesp32/Berry-0.1.10/src/port/berry_conf.h b/lib/libesp32/Berry/default/berry_conf.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/berry_conf.h rename to lib/libesp32/Berry/default/berry_conf.h diff --git a/lib/libesp32/Berry-0.1.10/src/port/gpio.txt b/lib/libesp32/Berry/default/gpio.txt similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/port/gpio.txt rename to lib/libesp32/Berry/default/gpio.txt diff --git a/lib/libesp32/Berry/examples/anon_func.be b/lib/libesp32/Berry/examples/anon_func.be new file mode 100644 index 000000000..78854ce64 --- /dev/null +++ b/lib/libesp32/Berry/examples/anon_func.be @@ -0,0 +1,20 @@ +# anonymous function and closure +def count(x) + var arr = [] + for i : 0 .. x + arr.push( + def (n) # loop variable cannot be used directly as free variable + return def () + return n * n + end + end (i) # define and call anonymous function + ) + end + return arr +end + +for xx : count(6) + print(xx()) # 0, 1, 4 ... n * n +end + +return count diff --git a/lib/libesp32/Berry/examples/bigloop.be b/lib/libesp32/Berry/examples/bigloop.be new file mode 100644 index 000000000..a3a77768b --- /dev/null +++ b/lib/libesp32/Berry/examples/bigloop.be @@ -0,0 +1,15 @@ +import time + +c = time.clock() +do + i = 0 + while i < 100000000 + i += 1 + end +end +print('while iteration 100000000 times', time.clock() - c, 's') + +c = time.clock() +for i : 1 .. 100000000 +end +print('for iteration 100000000 times', time.clock() - c, 's') diff --git a/lib/libesp32/Berry/examples/bintree.be b/lib/libesp32/Berry/examples/bintree.be new file mode 100644 index 000000000..81936f8a0 --- /dev/null +++ b/lib/libesp32/Berry/examples/bintree.be @@ -0,0 +1,60 @@ +# Reference from https://github.com/BerryMathDevelopmentTeam/BerryMath/blob/master/testscript/BinaryTree.bm + +class node + var v, l, r + def init(v, l, r) + self.v = v + self.l = l + self.r = r + end + def insert(v) + if v < self.v + if self.l + self.l.insert(v) + else + self.l = node(v) + end + else + if self.r + self.r.insert(v) + else + self.r = node (v) + end + end + end + def sort(l) + if (self.l) self.l.sort(l) end + l.push(self.v) + if (self.r) self.r.sort(l) end + end +end + +class btree + var root + def insert(v) + if self.root + self.root.insert(v) + else + self.root = node(v) + end + end + def sort() + var l = [] + if self.root + self.root.sort(l) + end + return l + end +end + +var tree = btree() +tree.insert(-100) +tree.insert(5); +tree.insert(3); +tree.insert(9); +tree.insert(10); +tree.insert(10000000); +tree.insert(1); +tree.insert(-1); +tree.insert(-10); +print(tree.sort()); diff --git a/lib/libesp32/Berry/examples/calcpi.be b/lib/libesp32/Berry/examples/calcpi.be new file mode 100644 index 000000000..053f87875 --- /dev/null +++ b/lib/libesp32/Berry/examples/calcpi.be @@ -0,0 +1,16 @@ +def cpi(n) + i = 2 + pi = 3 + while i <= n + term = 4.0 / (i * (i + 1) * (i + 2)) + if i % 4 + pi = pi + term + else + pi = pi - term + end + i = i + 2 + end + return pi +end + +print("pi =", cpi(100)) diff --git a/lib/libesp32/Berry/examples/exception.be b/lib/libesp32/Berry/examples/exception.be new file mode 100644 index 000000000..3a3098dce --- /dev/null +++ b/lib/libesp32/Berry/examples/exception.be @@ -0,0 +1,12 @@ +import debug + +def test_func() + try + compile('def +() end')() + except .. as e, v + print('catch execption:', str(e) + ' >>>\n ' + str(v)) + debug.traceback() + end +end + +test_func() diff --git a/lib/libesp32/Berry/examples/fib_rec.be b/lib/libesp32/Berry/examples/fib_rec.be new file mode 100644 index 000000000..31ed3817b --- /dev/null +++ b/lib/libesp32/Berry/examples/fib_rec.be @@ -0,0 +1,12 @@ +import time + +def fib(x) + if x <= 2 + return 1 + end + return fib(x - 1) + fib(x - 2) +end + +c = time.clock() +print("fib:", fib(38)) # minimum stack size: 78!! +print("time:", time.clock() - c, 's') diff --git a/lib/libesp32/Berry/examples/guess_number.be b/lib/libesp32/Berry/examples/guess_number.be new file mode 100644 index 000000000..6cbd07e7c --- /dev/null +++ b/lib/libesp32/Berry/examples/guess_number.be @@ -0,0 +1,26 @@ +import time +import math + +math.srand(time.time()) +res = math.rand() % 100 +max_test = 7 +test = -1 +idx = 1 +print('Guess a number between 0 and 99. You have', max_test, 'chances.') +while test != res && idx <= max_test + test = number(input(str(idx) + ': enter the number you guessed: ')) + if type(test) != 'int' + print('This is not an integer. Continue!') + continue + elif test > res + print('This number is too large.') + elif test < res + print('This number is too small.') + end + idx = idx + 1 +end +if test == res + print('You win!') +else + print('You failed, the correct answer is', res) +end diff --git a/lib/libesp32/Berry/examples/json.be b/lib/libesp32/Berry/examples/json.be new file mode 100644 index 000000000..d98dff8bb --- /dev/null +++ b/lib/libesp32/Berry/examples/json.be @@ -0,0 +1,4 @@ +import json +print(json.load('{"key": "value"}')) +print(json.dump({'test key': nil})) +print(json.dump({'key1': nil, 45: true}, 'format')) diff --git a/lib/libesp32/Berry/examples/lambda.be b/lib/libesp32/Berry/examples/lambda.be new file mode 100644 index 000000000..1d0b709bb --- /dev/null +++ b/lib/libesp32/Berry/examples/lambda.be @@ -0,0 +1,8 @@ +# simple lambda example +print((/a b c-> a * b + c)(2, 3, 4)) + +# Y-Combinator and factorial functions +Y = /f-> (/x-> f(/n-> x(x)(n)))(/x-> f(/n-> x(x)(n))) +F = /f-> /x-> x ? f(x - 1) * x : 1 +fact = Y(F) +print('fact(10) == ' .. fact(10)) diff --git a/lib/libesp32/Berry/examples/listdir.be b/lib/libesp32/Berry/examples/listdir.be new file mode 100644 index 000000000..2dd880118 --- /dev/null +++ b/lib/libesp32/Berry/examples/listdir.be @@ -0,0 +1,16 @@ +import os + +def scandir(path) + print('path: ' + path) + for name : os.listdir(path) + var fullname = os.path.join(path, name) + if os.path.isfile(fullname) + print('file: ' + fullname) + else + print('path: ' + fullname) + scandir(fullname) + end + end +end + +scandir('.') diff --git a/lib/libesp32/Berry/examples/qsort.be b/lib/libesp32/Berry/examples/qsort.be new file mode 100644 index 000000000..b09b65672 --- /dev/null +++ b/lib/libesp32/Berry/examples/qsort.be @@ -0,0 +1,42 @@ +def qsort(data) + # do once sort + def once(left, right) + var pivot = data[left] # use the 0th value as the pivot + while left < right # check if sort is complete + # put the value less than the pivot to the left + while left < right && data[right] >= pivot + right -= 1 # skip values greater than pivot + end + data[left] = data[right] + # put the value greater than the pivot on the right + while left < right && data[left] <= pivot + left += 1 # skip values less than pivot + end + data[right] = data[left] + end + # now we have the index of the pivot, store it + data[left] = pivot + return left # return the index of the pivot + end + # recursive quick sort algorithm + def _sort(left, right) + if left < right # executed when the array is not empty + var index = once(left, right) # get index of pivot for divide and conquer + _sort(left, index - 1) # sort the data on the left + _sort(index + 1, right) # sort the data on the right + end + end + # start quick sort + _sort(0, data.size() - 1) + return data +end + +import time, math +math.srand(time.time()) # sse system time as a random seed +data = [] +# put 20 random numbers into the array +for i : 1 .. 20 + data.push(math.rand() % 100) +end +# sort and print +print(qsort(data)) diff --git a/lib/libesp32/Berry/examples/repl.be b/lib/libesp32/Berry/examples/repl.be new file mode 100644 index 000000000..aac26b0a1 --- /dev/null +++ b/lib/libesp32/Berry/examples/repl.be @@ -0,0 +1,61 @@ +do + def ismult(msg) + import string + return string.split(msg, -5)[1] == '\'EOS\'' + end + + def multline(src, msg) + if !ismult(msg) + print('syntax_error: ' + msg) + return + end + while true + try + src += '\n' + input('>> ') + return compile(src) + except 'syntax_error' as e, m + if !ismult(m) + print('syntax_error: ' + m) + return + end + end + end + end + + def parse() + var fun, src = input('> ') + try + fun = compile('return (' + src + ')') + except 'syntax_error' as e, m + try + fun = compile(src) + except 'syntax_error' as e, m + fun = multline(src, m) + end + end + return fun + end + + def run(fun) + try + var res = fun() + if res print(res) end + except .. as e, m + import debug + print(e .. ': ' .. m) + debug.traceback() + end + end + + def repl() + while true + var fun = parse() + if fun != nil + run(fun) + end + end + end + + print("Berry Berry REPL!") + repl() +end diff --git a/lib/libesp32/Berry/examples/string.be b/lib/libesp32/Berry/examples/string.be new file mode 100644 index 000000000..299834e21 --- /dev/null +++ b/lib/libesp32/Berry/examples/string.be @@ -0,0 +1,32 @@ +s = "This is a long string test. 0123456789 abcdefg ABCDEFG" +print(s) + +a = .5 +print(a) + +import string as s + +print(s.hex(0x45678ABCD, 16)) + +def bin(x, num) + assert(type(x) == 'int', 'the type of \'x\' must be integer') + # test the 'x' bits + var bits = 1 + for i : 0 .. 62 + if x & (1 << 63 - i) + bits = 64 - i + break + end + end + if type(num) == 'int' && num > 0 && num <= 64 + bits = bits < num ? num : bits + end + var result = '' + bits -= 1 + for i : 0 .. bits + result += x & (1 << (bits - i)) ? '1' : '0' + end + return result +end + +print(bin(33)) diff --git a/lib/libesp32/Berry/examples/strmod.be b/lib/libesp32/Berry/examples/strmod.be new file mode 100644 index 000000000..8660f5b4e --- /dev/null +++ b/lib/libesp32/Berry/examples/strmod.be @@ -0,0 +1,7 @@ +import string + +print(string.format('%.3d', 12)) +print(string.format('%.3f', 12)) +print(string.format('%20.7f', 14.5)) +print(string.format('-- %-40s ---', 'this is a string format test')) +print(string.format('-- %40s ---', 'this is a string format test')) diff --git a/lib/libesp32/Berry-0.1.10/generate/be_const_strtab.h b/lib/libesp32/Berry/generate/be_const_strtab.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_const_strtab.h rename to lib/libesp32/Berry/generate/be_const_strtab.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_const_strtab_def.h b/lib/libesp32/Berry/generate/be_const_strtab_def.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_const_strtab_def.h rename to lib/libesp32/Berry/generate/be_const_strtab_def.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_bytes.h b/lib/libesp32/Berry/generate/be_fixed_be_class_bytes.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_bytes.h rename to lib/libesp32/Berry/generate/be_fixed_be_class_bytes.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_list.h b/lib/libesp32/Berry/generate/be_fixed_be_class_list.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_list.h rename to lib/libesp32/Berry/generate/be_fixed_be_class_list.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_map.h b/lib/libesp32/Berry/generate/be_fixed_be_class_map.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_map.h rename to lib/libesp32/Berry/generate/be_fixed_be_class_map.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_range.h b/lib/libesp32/Berry/generate/be_fixed_be_class_range.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_be_class_range.h rename to lib/libesp32/Berry/generate/be_fixed_be_class_range.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_debug.h b/lib/libesp32/Berry/generate/be_fixed_debug.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_debug.h rename to lib/libesp32/Berry/generate/be_fixed_debug.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_gc.h b/lib/libesp32/Berry/generate/be_fixed_gc.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_gc.h rename to lib/libesp32/Berry/generate/be_fixed_gc.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_gpio.h b/lib/libesp32/Berry/generate/be_fixed_gpio.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_gpio.h rename to lib/libesp32/Berry/generate/be_fixed_gpio.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_json.h b/lib/libesp32/Berry/generate/be_fixed_json.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_json.h rename to lib/libesp32/Berry/generate/be_fixed_json.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_m_builtin.h b/lib/libesp32/Berry/generate/be_fixed_m_builtin.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_m_builtin.h rename to lib/libesp32/Berry/generate/be_fixed_m_builtin.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_math.h b/lib/libesp32/Berry/generate/be_fixed_math.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_math.h rename to lib/libesp32/Berry/generate/be_fixed_math.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_os.h b/lib/libesp32/Berry/generate/be_fixed_os.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_os.h rename to lib/libesp32/Berry/generate/be_fixed_os.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_path.h b/lib/libesp32/Berry/generate/be_fixed_path.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_path.h rename to lib/libesp32/Berry/generate/be_fixed_path.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_solidify.h b/lib/libesp32/Berry/generate/be_fixed_solidify.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_solidify.h rename to lib/libesp32/Berry/generate/be_fixed_solidify.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_string.h b/lib/libesp32/Berry/generate/be_fixed_string.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_string.h rename to lib/libesp32/Berry/generate/be_fixed_string.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_sys.h b/lib/libesp32/Berry/generate/be_fixed_sys.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_sys.h rename to lib/libesp32/Berry/generate/be_fixed_sys.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_tasmota.h b/lib/libesp32/Berry/generate/be_fixed_tasmota.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_tasmota.h rename to lib/libesp32/Berry/generate/be_fixed_tasmota.h diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_time.h b/lib/libesp32/Berry/generate/be_fixed_time.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/generate/be_fixed_time.h rename to lib/libesp32/Berry/generate/be_fixed_time.h diff --git a/lib/libesp32/Berry/library.json b/lib/libesp32/Berry/library.json new file mode 100644 index 000000000..c1a6bf633 --- /dev/null +++ b/lib/libesp32/Berry/library.json @@ -0,0 +1,29 @@ +{ + "name":"Berry", + "description":"Berry scripting language for Tasmota32", + "keywords":"berry, script", + "authors": + { + "name": "Guan Wenliang , ", + "maintainer": true + }, + "repository": + { + "type": "git", + "url": "https://github.com/Skiars/berry" + }, + "version": "7.0", + "license": "MIT License", + "frameworks": "*", + "platforms": "*", + "build": { + "srcFilter": [ + "+<*.c>", + "+<../default/*.c>", + "+<../default/*.cpp>", + "+<../default/*.hpp>", + "+<*.cpp>", + "+<*.h>" + ] + } +} \ No newline at end of file diff --git a/lib/libesp32/Berry-0.1.10/src/be_api.c b/lib/libesp32/Berry/src/be_api.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_api.c rename to lib/libesp32/Berry/src/be_api.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_baselib.c b/lib/libesp32/Berry/src/be_baselib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_baselib.c rename to lib/libesp32/Berry/src/be_baselib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_bytecode.c b/lib/libesp32/Berry/src/be_bytecode.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_bytecode.c rename to lib/libesp32/Berry/src/be_bytecode.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_bytecode.h b/lib/libesp32/Berry/src/be_bytecode.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_bytecode.h rename to lib/libesp32/Berry/src/be_bytecode.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_byteslib.c b/lib/libesp32/Berry/src/be_byteslib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_byteslib.c rename to lib/libesp32/Berry/src/be_byteslib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_class.c b/lib/libesp32/Berry/src/be_class.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_class.c rename to lib/libesp32/Berry/src/be_class.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_class.h b/lib/libesp32/Berry/src/be_class.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_class.h rename to lib/libesp32/Berry/src/be_class.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_code.c b/lib/libesp32/Berry/src/be_code.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_code.c rename to lib/libesp32/Berry/src/be_code.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_code.h b/lib/libesp32/Berry/src/be_code.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_code.h rename to lib/libesp32/Berry/src/be_code.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_constobj.h b/lib/libesp32/Berry/src/be_constobj.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_constobj.h rename to lib/libesp32/Berry/src/be_constobj.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_debug.c b/lib/libesp32/Berry/src/be_debug.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_debug.c rename to lib/libesp32/Berry/src/be_debug.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_debug.h b/lib/libesp32/Berry/src/be_debug.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_debug.h rename to lib/libesp32/Berry/src/be_debug.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_debuglib.c b/lib/libesp32/Berry/src/be_debuglib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_debuglib.c rename to lib/libesp32/Berry/src/be_debuglib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_decoder.h b/lib/libesp32/Berry/src/be_decoder.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_decoder.h rename to lib/libesp32/Berry/src/be_decoder.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_exec.c b/lib/libesp32/Berry/src/be_exec.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_exec.c rename to lib/libesp32/Berry/src/be_exec.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_exec.h b/lib/libesp32/Berry/src/be_exec.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_exec.h rename to lib/libesp32/Berry/src/be_exec.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_filelib.c b/lib/libesp32/Berry/src/be_filelib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_filelib.c rename to lib/libesp32/Berry/src/be_filelib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_func.c b/lib/libesp32/Berry/src/be_func.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_func.c rename to lib/libesp32/Berry/src/be_func.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_func.h b/lib/libesp32/Berry/src/be_func.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_func.h rename to lib/libesp32/Berry/src/be_func.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_gc.c b/lib/libesp32/Berry/src/be_gc.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_gc.c rename to lib/libesp32/Berry/src/be_gc.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_gc.h b/lib/libesp32/Berry/src/be_gc.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_gc.h rename to lib/libesp32/Berry/src/be_gc.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_gclib.c b/lib/libesp32/Berry/src/be_gclib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_gclib.c rename to lib/libesp32/Berry/src/be_gclib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_jsonlib.c b/lib/libesp32/Berry/src/be_jsonlib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_jsonlib.c rename to lib/libesp32/Berry/src/be_jsonlib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_lexer.c b/lib/libesp32/Berry/src/be_lexer.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_lexer.c rename to lib/libesp32/Berry/src/be_lexer.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_lexer.h b/lib/libesp32/Berry/src/be_lexer.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_lexer.h rename to lib/libesp32/Berry/src/be_lexer.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_libs.c b/lib/libesp32/Berry/src/be_libs.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_libs.c rename to lib/libesp32/Berry/src/be_libs.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_libs.h b/lib/libesp32/Berry/src/be_libs.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_libs.h rename to lib/libesp32/Berry/src/be_libs.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_list.c b/lib/libesp32/Berry/src/be_list.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_list.c rename to lib/libesp32/Berry/src/be_list.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_list.h b/lib/libesp32/Berry/src/be_list.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_list.h rename to lib/libesp32/Berry/src/be_list.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_listlib.c b/lib/libesp32/Berry/src/be_listlib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_listlib.c rename to lib/libesp32/Berry/src/be_listlib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_map.c b/lib/libesp32/Berry/src/be_map.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_map.c rename to lib/libesp32/Berry/src/be_map.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_map.h b/lib/libesp32/Berry/src/be_map.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_map.h rename to lib/libesp32/Berry/src/be_map.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_maplib.c b/lib/libesp32/Berry/src/be_maplib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_maplib.c rename to lib/libesp32/Berry/src/be_maplib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_mathlib.c b/lib/libesp32/Berry/src/be_mathlib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_mathlib.c rename to lib/libesp32/Berry/src/be_mathlib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_mem.c b/lib/libesp32/Berry/src/be_mem.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_mem.c rename to lib/libesp32/Berry/src/be_mem.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_mem.h b/lib/libesp32/Berry/src/be_mem.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_mem.h rename to lib/libesp32/Berry/src/be_mem.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_module.c b/lib/libesp32/Berry/src/be_module.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_module.c rename to lib/libesp32/Berry/src/be_module.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_module.h b/lib/libesp32/Berry/src/be_module.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_module.h rename to lib/libesp32/Berry/src/be_module.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_object.c b/lib/libesp32/Berry/src/be_object.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_object.c rename to lib/libesp32/Berry/src/be_object.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_object.h b/lib/libesp32/Berry/src/be_object.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_object.h rename to lib/libesp32/Berry/src/be_object.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_opcodes.h b/lib/libesp32/Berry/src/be_opcodes.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_opcodes.h rename to lib/libesp32/Berry/src/be_opcodes.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_oslib.c b/lib/libesp32/Berry/src/be_oslib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_oslib.c rename to lib/libesp32/Berry/src/be_oslib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_parser.c b/lib/libesp32/Berry/src/be_parser.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_parser.c rename to lib/libesp32/Berry/src/be_parser.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_parser.h b/lib/libesp32/Berry/src/be_parser.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_parser.h rename to lib/libesp32/Berry/src/be_parser.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_rangelib.c b/lib/libesp32/Berry/src/be_rangelib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_rangelib.c rename to lib/libesp32/Berry/src/be_rangelib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_repl.c b/lib/libesp32/Berry/src/be_repl.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_repl.c rename to lib/libesp32/Berry/src/be_repl.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_repl.h b/lib/libesp32/Berry/src/be_repl.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_repl.h rename to lib/libesp32/Berry/src/be_repl.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_solidifylib.c b/lib/libesp32/Berry/src/be_solidifylib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_solidifylib.c rename to lib/libesp32/Berry/src/be_solidifylib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_string.c b/lib/libesp32/Berry/src/be_string.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_string.c rename to lib/libesp32/Berry/src/be_string.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_string.h b/lib/libesp32/Berry/src/be_string.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_string.h rename to lib/libesp32/Berry/src/be_string.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_strlib.c b/lib/libesp32/Berry/src/be_strlib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_strlib.c rename to lib/libesp32/Berry/src/be_strlib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_strlib.h b/lib/libesp32/Berry/src/be_strlib.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_strlib.h rename to lib/libesp32/Berry/src/be_strlib.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_sys.h b/lib/libesp32/Berry/src/be_sys.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_sys.h rename to lib/libesp32/Berry/src/be_sys.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_syslib.c b/lib/libesp32/Berry/src/be_syslib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_syslib.c rename to lib/libesp32/Berry/src/be_syslib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_timelib.c b/lib/libesp32/Berry/src/be_timelib.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_timelib.c rename to lib/libesp32/Berry/src/be_timelib.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_var.c b/lib/libesp32/Berry/src/be_var.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_var.c rename to lib/libesp32/Berry/src/be_var.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_var.h b/lib/libesp32/Berry/src/be_var.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_var.h rename to lib/libesp32/Berry/src/be_var.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_vector.c b/lib/libesp32/Berry/src/be_vector.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_vector.c rename to lib/libesp32/Berry/src/be_vector.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_vector.h b/lib/libesp32/Berry/src/be_vector.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_vector.h rename to lib/libesp32/Berry/src/be_vector.h diff --git a/lib/libesp32/Berry-0.1.10/src/be_vm.c b/lib/libesp32/Berry/src/be_vm.c similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_vm.c rename to lib/libesp32/Berry/src/be_vm.c diff --git a/lib/libesp32/Berry-0.1.10/src/be_vm.h b/lib/libesp32/Berry/src/be_vm.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/be_vm.h rename to lib/libesp32/Berry/src/be_vm.h diff --git a/lib/libesp32/Berry-0.1.10/src/berry.h b/lib/libesp32/Berry/src/berry.h similarity index 100% rename from lib/libesp32/Berry-0.1.10/src/berry.h rename to lib/libesp32/Berry/src/berry.h diff --git a/lib/libesp32/Berry/src/berry_conf.h b/lib/libesp32/Berry/src/berry_conf.h new file mode 100644 index 000000000..c0ec957c4 --- /dev/null +++ b/lib/libesp32/Berry/src/berry_conf.h @@ -0,0 +1 @@ +#include "../default/berry_conf.h" \ No newline at end of file diff --git a/lib/libesp32/Berry/testall.be b/lib/libesp32/Berry/testall.be new file mode 100755 index 000000000..57414dbc5 --- /dev/null +++ b/lib/libesp32/Berry/testall.be @@ -0,0 +1,44 @@ +#! ./berry +import os + +os.system('lcov', '-q -c -i -d . -o init.info') + +var exec = './berry' +var path = 'tests' +var testcases = os.listdir(path) +var total = 0, failed = 0 + +for i : testcases + if os.path.splitext(i)[1] == '.be' + print('\033[0;36mrun testcase: ' + i + '\033[0m') + var ret = os.system(exec, os.path.join(path, i)) + if ret != 0 + print('\033[0;31mreturn code:', ret, '\033[0m') + failed += 1 + end + total += 1 + end +end + +print('\033[0;32mtest results: ' + + str(total) + ' total, ' + str(failed) + ' failed' + + (failed ? '' : ' (all tests passed)') + + '.\033[0m') + +if failed != 0 + os.exit(-1) +end + +var cmds = [ + 'lcov -q -c -d ./ -o cover.info', + 'lcov -q -a init.info -a cover.info -o total.info', + 'lcov --remove total.info */usr/include/* -o final.info', + 'genhtml -q -o test_report --legend --title "lcov" --prefix=./ final.info', + 'rm -f init.info cover.info total.info final.info' +] + +for cmd : cmds + if os.system(cmd) + os.exit(-1) + end +end diff --git a/lib/libesp32/Berry/tests/assignment.be b/lib/libesp32/Berry/tests/assignment.be new file mode 100644 index 000000000..71bb81ebf --- /dev/null +++ b/lib/libesp32/Berry/tests/assignment.be @@ -0,0 +1,34 @@ +class Test + var a +end + +# continuous assignment of global suffix expressions +o = Test() +o.a = 100 +assert(o.a == 100) +o.a += 10 +assert(o.a == 110) + +p = Test() +p.a = Test() +p.a.a = 50 +assert(p.a.a == 50) +p.a.a += 10 +assert(p.a.a == 60) + +# continuous assignment of local suffix expressions +def test_func() + var o = Test() + o.a = 100 + assert(o.a == 100) + o.a += 10 + assert(o.a == 110) + + var p = Test() + p.a = Test() + p.a.a = 50 + assert(p.a.a == 50) + p.a.a += 10 + assert(p.a.a == 60) +end +test_func() diff --git a/lib/libesp32/Berry/tests/bool.be b/lib/libesp32/Berry/tests/bool.be new file mode 100644 index 000000000..670f9bfd8 --- /dev/null +++ b/lib/libesp32/Berry/tests/bool.be @@ -0,0 +1,18 @@ +# test cases for boolean expressions + +assert(1 != false && 1 != true) +assert(0 != false && 0 != true) +assert(!!1 == true) +assert(!!0 == false) + +a = true +b = false +assert(!!list == true) +assert(a && b == false) +assert(!(a && b)) +def test(a, b) + while !(a && b) + assert(false) + end +end +test(true, true) diff --git a/lib/libesp32/Berry/tests/bytes.be b/lib/libesp32/Berry/tests/bytes.be new file mode 100644 index 000000000..cce46120f --- /dev/null +++ b/lib/libesp32/Berry/tests/bytes.be @@ -0,0 +1,167 @@ +#- basic initialization -# +b=bytes() +assert(str(b) == "bytes('')") +b=bytes("") +assert(str(b) == "bytes('')") +b=bytes(0) +assert(str(b) == "bytes('')") +b=bytes(1) +assert(str(b) == "bytes('')") +b=bytes(-1) +assert(str(b) == "bytes('')") +assert(b.size() == 0) + +b=bytes("a") +assert(str(b) == "bytes('')") +b=bytes(3.5) +assert(str(b) == "bytes('')") +b=bytes([]) +assert(str(b) == "bytes('')") + +b=bytes("1122AAaaBBbb") +assert(str(b) == "bytes('1122AAAABBBB')") +assert(b.size() == 6) +b=bytes("112") +assert(str(b) == "bytes('11')") +b=bytes("++") +assert(str(b) == "bytes('00')") + +#- add -# +b=bytes() +b.add(0x22) +assert(str(b) == "bytes('22')") +b.add(0x12345678, 0) +assert(str(b) == "bytes('22')") +b.add(0x12345678, 1) +assert(str(b) == "bytes('2278')") +b.add(0x12345678, 2) +assert(str(b) == "bytes('22787856')") +b.add(0x12345678, 4) +assert(str(b) == "bytes('2278785678563412')") +b.add(0x12345678, -1) #- big endian -# +assert(str(b) == "bytes('227878567856341278')") +b.add(0x12345678, -2) +assert(str(b) == "bytes('2278785678563412785678')") +b.add(0x12345678, -4) +assert(str(b) == "bytes('227878567856341278567812345678')") + +#- get -# +b=bytes("000102030405") +assert(b.get(0) == 0) +assert(b.get(-1) == 0) #- could consider nil as well -# +assert(b.get(6) == 0) #- could consider nil as well -# +assert(b.get(1) == 1) +assert(b.get(5) == 5) + +assert(b.get(1,0) == nil) +assert(b.get(1,1) == 0x01) +assert(b.get(1,2) == 0x0201) +assert(b.get(1,4) == 0x04030201) +assert(b.get(1,-1) == 0x01) +assert(b.get(1,-2) == 0x0102) #- big endian -# +assert(b.get(1,-4) == 0x01020304) + +#- resize -# +assert(bytes().size() == 0) +b=bytes("112233") +b.resize(2) +assert(str(b) == "bytes('1122')") +assert(b.size() == 2) +b.resize(4) +assert(str(b) == "bytes('11220000')") +assert(b.size() == 4) +b.resize(20) +assert(str(b) == "bytes('1122000000000000000000000000000000000000')") +assert(b.size() == 20) +b.resize(0) +assert(str(b) == "bytes('')") +assert(b.size() == 0) + +#- clear -# +b=bytes("aabb") +b.clear() +assert(str(b) == "bytes('')") + +#- == != -# +assert(bytes() == bytes()) +assert(bytes("11") == bytes("11")) +assert(bytes("11") == bytes()..0x11) +assert(! (bytes("11") == bytes(0x12)) ) +assert(! (bytes("11") == 0x11) ) +assert(! (bytes("11") != bytes("11")) ) +assert(bytes("11") != bytes("1122")) +assert(bytes("11") != bytes("12")) +assert(bytes("11") != bytes()) + +#- + -# +b1 = bytes("1122") +b2 = bytes("334455") +b = b1 + b2 +assert(str(b1) == "bytes('1122')") +assert(str(b2) == "bytes('334455')") +assert(str(b) == "bytes('1122334455')") +b = b2 + b1 +assert(str(b) == "bytes('3344551122')") + +#- .. -# +b1 = bytes("1122") +b2 = bytes("334455") +b = b1..b2 +assert(str(b1) == "bytes('1122334455')") +assert(str(b2) == "bytes('334455')") +assert(str(b) == "bytes('1122334455')") + +#- item -# +b = bytes("334455") +assert(b[0] == 0x33) +assert(b[1] == 0x44) +assert(b[2] == 0x55) + +#- item range -# +b = bytes("00112233445566778899AABBCCDDEEFF") +assert(str(b[1..1]) =="bytes('11')") +assert(str(b[-11..1]) =="bytes('0011')") +assert(str(b[0..40]) =="bytes('00112233445566778899AABBCCDDEEFF')") +assert(str(b[1..0]) =="bytes('')") + +#- copy -# +b=bytes("112233") +b2=b.copy() +assert(str(b) =="bytes('112233')") +assert(str(b2) =="bytes('112233')") +b2.clear() +assert(str(b) =="bytes('112233')") +assert(str(b2) =="bytes('')") + +#- setitem -# +b=bytes("112233") +assert(str(b) =="bytes('112233')") +b[1]=0xAA +assert(str(b) =="bytes('11AA33')") +b[0]=0xBB +assert(str(b) =="bytes('BBAA33')") +b[2]=-1 +assert(str(b) =="bytes('BBAAFF')") + +#- resize -# +b=bytes() +b.resize(20) +assert(str(b) =="bytes('0000000000000000000000000000000000000000')") +b2=b.copy() +assert(str(b2) =="bytes('0000000000000000000000000000000000000000')") + +#- asstring -# +b=bytes() +assert(b.asstring() == '') +b=bytes("334455") +assert(b.asstring() == '3DU') +b=bytes("33456502") +assert(b.asstring() == '3Ee\x02') + +#- fromstring -# +b=bytes() +b.fromstring("Aa0") +assert(str(b) =="bytes('416130')") +b=bytes() +b.fromstring("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.") +assert(str(b) =="bytes('4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742C2073656420646F20656975736D6F642074656D706F7220696E6369646964756E74207574206C61626F726520657420646F6C6F7265206D61676E6120616C697175612E')") diff --git a/lib/libesp32/Berry/tests/checkspace.be b/lib/libesp32/Berry/tests/checkspace.be new file mode 100644 index 000000000..f4079d952 --- /dev/null +++ b/lib/libesp32/Berry/tests/checkspace.be @@ -0,0 +1,35 @@ +import os + +def strfind(str, char) + var len = size(str) + for i : 0 .. len - 1 + if str[i] == char + return true + end + end + return false +end + +def checkfile(path) + var subname = os.path.splitext(path)[1] + if (subname == '.c' || subname == '.h' || + subname == '.cpp' || subname == '.be' || subname == '.json') + var f = open(path) + assert(!strfind(f.read(), '\t'), 'file \'' + path + '\' has tab character') + f.close() + end +end + +def findpath(path) + var ls = os.listdir(path) + for name : ls + var fullname = os.path.join(path, name) + if os.path.isfile(fullname) + checkfile(fullname) + elif fullname != '.' && fullname != '..' + findpath(fullname) + end + end +end + +findpath('.') diff --git a/lib/libesp32/Berry/tests/class.be b/lib/libesp32/Berry/tests/class.be new file mode 100644 index 000000000..fb310e802 --- /dev/null +++ b/lib/libesp32/Berry/tests/class.be @@ -0,0 +1,22 @@ +class Test + var maximum + def init(maximum) + self.maximum = maximum + end + def iter() # method closure upvalues test + var i = -1, maximum = self.maximum + return def () + i += 1 + if i > maximum + raise 'stop_iteration' + end + return i + end + end +end + +var sum = 0 +for i : Test(10) + sum += i +end +assert(sum == 55, 'iteraion sum is ' + str(sum) + ' (expected 55).') diff --git a/lib/libesp32/Berry/tests/cond_expr.be b/lib/libesp32/Berry/tests/cond_expr.be new file mode 100644 index 000000000..dc70fd306 --- /dev/null +++ b/lib/libesp32/Berry/tests/cond_expr.be @@ -0,0 +1,10 @@ +assert("" != 0 ? true : false) +assert(false || !(true ? false : true) && true) +var t1 = 8, t2 = false +if t1 ? 7 + t1 : t2 + var a = 'good' + assert((a == 'good' ? a + '!' : a) == 'good!') + assert((a == 'good?' ? a + '!' : a) != 'good!') +else + assert('condition expression test failed') +end diff --git a/lib/libesp32/Berry/tests/debug.be b/lib/libesp32/Berry/tests/debug.be new file mode 100644 index 000000000..9e732f6c3 --- /dev/null +++ b/lib/libesp32/Berry/tests/debug.be @@ -0,0 +1,4 @@ +import debug + +class A end +debug.attrdump(A) #- should not crash -# \ No newline at end of file diff --git a/lib/libesp32/Berry/tests/for.be b/lib/libesp32/Berry/tests/for.be new file mode 100644 index 000000000..ec4a910cd --- /dev/null +++ b/lib/libesp32/Berry/tests/for.be @@ -0,0 +1,44 @@ +var global + +global = 0 +for i : 0 .. 10 + global += i +end +assert(global == 55) + +global = 0 +for i : 0 .. 20 + if i > 10 + break + end + global += i +end +assert(global == 55) + +global = 0 +for i : 0 .. 20 + if i > 10 + continue + end + global += i +end +assert(global == 55) + +assert(def () + for i : 0 .. 20 + if i > 10 + return i + end + end + end() == 11) + +# test for "stop_iteration" exception as recurrence +def for_rec(depth) + for i : 0 .. 10 + if i == 4 && depth < 200 + for_rec(depth + 1) + end + end +end + +for_rec(0) diff --git a/lib/libesp32/Berry/tests/function.be b/lib/libesp32/Berry/tests/function.be new file mode 100644 index 000000000..81310408b --- /dev/null +++ b/lib/libesp32/Berry/tests/function.be @@ -0,0 +1,12 @@ +# CLOSE opcode test +var gbl +def func1() + var a = 'func1_a' + def func2() + return a + end + gbl = func2 + return 400000 + 500 +end +assert(func1() == 400500) +assert(gbl() == 'func1_a') diff --git a/lib/libesp32/Berry/tests/json.be b/lib/libesp32/Berry/tests/json.be new file mode 100644 index 000000000..ee009755b --- /dev/null +++ b/lib/libesp32/Berry/tests/json.be @@ -0,0 +1,53 @@ +import json + +# load tests + +def assert_load(text, value) + assert(json.load(text) == value) +end + +def assert_load_failed(text) + assert(json.load(text) == nil) +end + +assert_load('null', nil) +assert_load('true', true) +assert_load('false', false) +assert_load('123', 123) +assert_load('12.3', 12.3) +assert_load('"abc"', 'abc') +# strings +assert_load('"\\"\\\\\\/\\b\\f\\n\\r\\t"', '\"\\/\b\f\n\r\t') +assert_load('"\\u1234\\u2345\\u04aF\\u003A"', 'ሴ⍅ү:') +assert_load_failed('"\\u3fr"'); +assert_load_failed('"\\q"'); +assert_load_failed('"123'); +# list +assert_load('[1, null]', [1, nil]) +assert_load_failed('[x]') +assert_load_failed('[1, nil]') +assert_load_failed('[1, null') +# object +var o = json.load('{"key": 1}') +assert(o['key'] == 1 && o.size() == 1) +assert_load_failed('{"ke: 1}') +assert_load_failed('{"key": 1x}') +assert_load_failed('{"key"}') +assert_load_failed('{"key": 1, }') + +# dump tests + +def assert_dump(value, text, format) + assert(json.dump(value, format) == text) +end + +assert_dump(nil, 'null'); +assert_dump(true, 'true'); +assert_dump(false, 'false'); +assert_dump(1.23, '1.23'); +assert_dump('String', '"String"'); +assert_dump([1, 'x'], '[1,"x"]'); +assert_dump({1: 'x'}, '{"1":"x"}'); +assert_dump([1, 'x'], '[\n 1,\n "x"\n]', 'format'); +assert_dump({1: 'x'}, '{\n "1": "x"\n}', 'format'); +assert_dump({1: 'x', 'k': 'v'}, '{"k":"v","1":"x"}'); diff --git a/lib/libesp32/Berry/tests/lexer.be b/lib/libesp32/Berry/tests/lexer.be new file mode 100644 index 000000000..3dc34169d --- /dev/null +++ b/lib/libesp32/Berry/tests/lexer.be @@ -0,0 +1,62 @@ +import math + +def check(a, b) + assert(math.abs(a - b) < 1e-6) +end + +def test_source(src, msg) + try + compile(src) + assert(false, 'unexpected execution flow') + except .. as e, m + assert(e == 'syntax_error') + assert(m == 'string:1: ' + msg) + end +end + +#---- + this is a + mult-line comment +----# + +compile('x = 5; 0..x') +assert('\x5a' == 'Z') +assert('\132' == 'Z') +assert('\a\b\f\n\r\t\v\\\'\"\?' == '\x07\x08\x0c\x0a\x0d\x09\x0b\x5c\x27\x22\x3f') +assert(.45 == 0.45) +assert(0X10 == 16) +assert(0x10 == 16) +assert(0X1A == 26) +assert(0x1a == 26) +check(45., 45) +check(45.e-1, 4.5) +check(45.E-1, 4.5) +check(45.1e-1, 4.51) +check(45.1e2, 4510) +check(45.e2, 4500) +check(45.e+2, 4500) + +test_source('x = 5; 0...x;', 'unexpected symbol near \'.\'') +test_source('x = 5; 0...x;', 'unexpected symbol near \'.\'') +test_source('45..', 'unexpected symbol near \'EOS\'') +test_source('0xg', 'invalid hexadecimal number') +test_source('"\\x5g"', 'invalid hexadecimal number') +test_source('0x5g', 'malformed number') +test_source('"\\779"', 'invalid octal number') +test_source('"\n', 'unfinished string') + +var malformed_numbers = [ + '45f', + '45.f', + '45.ef', + '45.e-f', + '45.e-1f', + '45.e-1.', + '45.5.', + '0x45.', + '0x45j' +] + +for i : malformed_numbers + test_source(i, 'malformed number') +end diff --git a/lib/libesp32/Berry/tests/list.be b/lib/libesp32/Berry/tests/list.be new file mode 100644 index 000000000..a6ec7ecc7 --- /dev/null +++ b/lib/libesp32/Berry/tests/list.be @@ -0,0 +1,74 @@ +l = [1, 2, 3, 4, 5] +assert(l[0] == 1) +assert(l[1] == 2) +assert(l[2] == 3) +assert(l[3] == 4) +assert(l[4] == 5) +assert(str(l) == '[1, 2, 3, 4, 5]') + +it = l.iter() +assert(it() == 1) +assert(it() == 2) +assert(it() == 3) +assert(it() == 4) +assert(it() == 5) + +l.insert(0, 10) +assert(l[0] == 10) +assert(l.size() == 6) +l.remove(0) +assert(l.size() == 5) +assert(l[0] == 1) +l.setitem(0, 42) +assert(l[0] == 42) +assert(l.item(2) == 3) +l.resize(10) +assert(l.size() == 10) +assert(l.tostring() == '[42, 2, 3, 4, 5, nil, nil, nil, nil, nil]') + +assert(([] == []) == true) +assert(([] != []) == false) +assert(([1] == [1]) == true) +assert(([1] != [1]) == false) +assert(([1] == [0]) == false) +assert(([1] != [0]) == true) +assert(([1, 2, 3] == [1, 2, 3]) == true) +assert(([1, 2, 3] != [1, 2, 3]) == false) +assert(([1, 2, 3] == [1, 2, 4]) == false) +assert(([1, 2, 3] != [1, 2, 4]) == true) +assert(([1, 2, ['w']] == [1, 2, ['w']]) == true) +assert(([1, 2, ['w']] != [1, 2, ['w']]) == false) +assert(([1, 2, ['w']] == [1, 2, ['z']]) == false) +assert(([1, 2, ['w']] != [1, 2, ['z']]) == true) +assert(([1, 2, ['w']] == [1, 2, []]) == false) +assert(([1, 2, ['w']] != [1, 2, []]) == true) + +var l = [0, 1, 2, 3] +assert(l[-1] == 3) +assert(l[-2] == 2) +var t = l.copy() +l.insert(-2, 4) +assert(t == [0, 1, 2, 3] && t != l) +assert(l == [0, 1, 4, 2, 3]) +l.remove(-2) +assert(l == [0, 1, 4, 3]) +assert(l.reverse() == [3, 4, 1, 0]) +assert(l + [5, 6] == [3, 4, 1, 0, 5, 6]) +l = [0] +assert(l .. '3' == [0, '3']) +l.push(1) +assert(l == [0, '3', 1]) +assert(l.concat() == '031') +l.pop() +assert(l == [0, '3']) +l.pop(0) +assert(l == ['3']) + +l1 = [0, 1] +l2 = [2, 3] +assert(l1+l2==[0, 1, 2, 3]) +assert(l1 == [0, 1]) +assert(l2 == [2, 3]) +assert(l1+[2] == [0, 1, 2]) +assert([-1]+l1 == [-1, 0, 1]) +assert(l1 == [0, 1]) diff --git a/lib/libesp32/Berry/tests/os.be b/lib/libesp32/Berry/tests/os.be new file mode 100644 index 000000000..37811bef1 --- /dev/null +++ b/lib/libesp32/Berry/tests/os.be @@ -0,0 +1,51 @@ +import os + +# os.path.join test +assert(os.path.join('') == '') +assert(os.path.join('abc', 'de') == 'abc/de') +assert(os.path.join('abc', '/de') == '/de') +assert(os.path.join('a', 'de') == 'a/de') +assert(os.path.join('abc/', 'de') == 'abc/de') +assert(os.path.join('abc', 'de', '') == 'abc/de/') +assert(os.path.join('abc', '', '', 'de') == 'abc/de') +assert(os.path.join('abc', '/de', 'fghij') == '/de/fghij') +assert(os.path.join('abc', 'xyz', '/de', 'fghij') == '/de/fghij') + +# os.path.split test +def split(str, list) + var res = os.path.split(str) + assert(res[0] == list[0] && res[1] == list[1], + 'unexpected results: ' .. res .. ', reference value: ' .. list) +end + +split('/', ['/', '']) +split('//', ['//', '']) +split('///', ['///', '']) +split('a/', ['a', '']) +split('a//', ['a', '']) +split('a/b/c', ['a/b', 'c']) +split('a/b/', ['a/b', '']) +split('a//b//', ['a//b', '']) +split('a/../b', ['a/..', 'b']) +split('abcd////ef/////', ['abcd////ef', '']) +split('abcd////ef', ['abcd', 'ef']) + +# os.path.splitext test +def splitext(str, list) + var res = os.path.splitext(str) + assert(res[0] == list[0] && res[1] == list[1], + 'unexpected results: ' .. res .. ', reference value: ' .. list) +end + +splitext('a.b', ['a', '.b']) +splitext('a..b', ['a.', '.b']) +splitext('/a..b', ['/a.', '.b']) +splitext('/.b', ['/.b', '']) +splitext('/..b', ['/..b', '']) +splitext('..b', ['..b', '']) +splitext('...b', ['...b', '']) +splitext('.b', ['.b', '']) +splitext('ac..b', ['ac.', '.b']) +splitext('ac.b', ['ac', '.b']) +splitext('ac/.b', ['ac/.b', '']) +splitext('ac/..b', ['ac/..b', '']) diff --git a/lib/libesp32/Berry/tests/overload.be b/lib/libesp32/Berry/tests/overload.be new file mode 100644 index 000000000..a9e72081b --- /dev/null +++ b/lib/libesp32/Berry/tests/overload.be @@ -0,0 +1,14 @@ +class test + def init() + self._a = 123 + end + def +() + return self._a + end + def ()() + return self._a + end + var _a +end + +print(test() + test()) diff --git a/lib/libesp32/Berry/tests/relop.be b/lib/libesp32/Berry/tests/relop.be new file mode 100644 index 000000000..a9a9805f1 --- /dev/null +++ b/lib/libesp32/Berry/tests/relop.be @@ -0,0 +1,40 @@ +def assert_true(status) + assert(status == true, 'assert(true) failed!') +end + +def assert_false(status) + assert(status == false, 'assert(false) failed!') +end + +assert_true(0 == 0) +assert_false(0 != 0) +assert_true(0 != 1) +assert_false(0 == 1) + + +assert_true(0.0 == 0) +assert_false(0.0 != 0) +assert_true(0.0 != 1.0) +assert_false(0.0 == 1.0) + +assert_true(nil == nil) +assert_false(nil != nil) +assert_true(true != nil) +assert_false(true == nil) +assert_true(nil != false) +assert_false(nil == false) + +assert_true(list == list) +assert_false(list == map) + +assert_true([] == []) +assert_true([true] == [true]) +assert_true([[]] == [[]]) +assert_false([[]] != [[]]) +assert_false([0] == []) +assert_false([] != []) +assert_true([] != nil) +assert_false([] == nil) + +assert_true({} != nil) +assert_false({} == nil) diff --git a/lib/libesp32/Berry/tests/string.be b/lib/libesp32/Berry/tests/string.be new file mode 100644 index 000000000..fad58f935 --- /dev/null +++ b/lib/libesp32/Berry/tests/string.be @@ -0,0 +1,30 @@ +import string as s + +assert(s.find('012345', '23') == 2) +assert(s.find('012345', '23', 1) == 2) +assert(s.find('012345', '23', 1, 3) == -1) +assert(s.find('012345', '23', 2, 4) == 2) +assert(s.find('012345', '23', 3) == -1) + +assert(s.find('012345', '') == 0) +assert(s.find('012345', '', 0, 0) == 0) +assert(s.find('012345', '', 1) == 1) +assert(s.find('012345', '', 1, 1) == 1) +assert(s.find('012345', '', 1, 0) == -1) +assert(s.find('012345', '', 6) == 6) +assert(s.find('012345', '', 7) == -1) + +assert(s.count('012345', '') == 7) +assert(s.count('012345', '', 2) == 5) +assert(s.count('012345', '', 6) == 1) + +assert(s.count('121314', '1') == 3) +assert(s.count('121314', '1', 1) == 2) +assert(s.count('121314', '1', 2) == 2) +assert(s.count('121314', '1', 1, 2) == 0) +assert(s.count('121314', '1', 1, 3) == 1) + +assert(s.split('a b c d e f', '1') == ['a b c d e f']) +assert(s.split('a b c d e f', ' ') == ['a', 'b', 'c', 'd', 'e', 'f']) +assert(s.split('a b c d e f', ' ', 2) == ['a', 'b', 'c d e f']) +assert(s.split('a b c d e f', '') == ['a b c d e f']) diff --git a/lib/libesp32/Berry/tests/subobject.be b/lib/libesp32/Berry/tests/subobject.be new file mode 100644 index 000000000..010e8af29 --- /dev/null +++ b/lib/libesp32/Berry/tests/subobject.be @@ -0,0 +1,29 @@ +class mylist : classof([]) end + +assert(issubclass(mylist, list) == true) +assert(issubclass(mylist, []) == true) +assert(issubclass(mylist(), list) == false) +assert(issubclass(mylist(), []) == false) + +assert(isinstance(mylist, list) == false) +assert(isinstance(mylist, []) == false) +assert(isinstance(mylist(), list) == true) +assert(isinstance(mylist(), []) == true) + +assert(issubclass(list, list) == true) +assert(issubclass(list, []) == true) +assert(issubclass(list(), list) == false) +assert(issubclass(list(), []) == false) + +assert(isinstance(list, list) == false) +assert(isinstance(list, []) == false) +assert(isinstance(list(), list) == true) +assert(isinstance(list(), []) == true) + +assert(issubclass(list, list) == true) +assert(issubclass(list, []) == true) +assert(issubclass(list(), list) == false) +assert(issubclass(list(), []) == false) + +assert(issubclass(list, mylist) == false) +assert(isinstance([], mylist) == false) diff --git a/lib/libesp32/Berry/tests/suffix.be b/lib/libesp32/Berry/tests/suffix.be new file mode 100644 index 000000000..222b092d8 --- /dev/null +++ b/lib/libesp32/Berry/tests/suffix.be @@ -0,0 +1,11 @@ +var keys = [ 'key1', 'key2', 'key3', 'key4' ] +var pairs = { + keys[0]: 'value1', + keys[1]: 'value2', + keys[2]: 'value3', + keys[3]: 'value4' +} + +for i : 0 .. keys.size() - 1 + assert(pairs[keys[i]] == 'value' .. i + 1) +end diff --git a/lib/libesp32/Berry/tools/coc/.gitignore b/lib/libesp32/Berry/tools/coc/.gitignore new file mode 100644 index 000000000..be1fbe796 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/.gitignore @@ -0,0 +1 @@ +coc diff --git a/lib/libesp32/Berry/tools/coc/Makefile b/lib/libesp32/Berry/tools/coc/Makefile new file mode 100644 index 000000000..773994b3c --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/Makefile @@ -0,0 +1,26 @@ +TARGET = coc +CXXFLAGS = -std=c++11 -O2 +CXX = g++ + +OBJS = coc_string.o \ + hash_map.o \ + macro_table.o \ + main.o \ + block_builder.o \ + str_build.o \ + coc_parser.o + +ifeq ($(OS), Windows_NT) # Windows + TARGET := $(TARGET).exe +endif + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(Q) $(CXX) $(OBJS) -o $@ + +$(OBJS): %.o: %.cpp + $(Q) $(CXX) $(CXXFLAGS) -c $< -o $@ + +clean: + $(Q) $(RM) $(OBJS) diff --git a/lib/libesp32/Berry/tools/coc/REEADME.md b/lib/libesp32/Berry/tools/coc/REEADME.md new file mode 100644 index 000000000..329c66d46 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/REEADME.md @@ -0,0 +1,3 @@ +# The Constant Object Compiler (coc) + +The constant object compiler (coc) is a C preprocessor that generates the corresponding C99 code based on the constant object declaration block. diff --git a/lib/libesp32/Berry/tools/coc/block_builder.cpp b/lib/libesp32/Berry/tools/coc/block_builder.cpp new file mode 100755 index 000000000..eecf9fd8e --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/block_builder.cpp @@ -0,0 +1,197 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "block_builder.h" +#include "hash_map.h" +#include "macro_table.h" +#include "object_block.h" +#include +#include + +static bool depend(const object_block *object, const macro_table *macro) +{ + auto it = object->attr.find("depend"); + if (it != object->attr.end()) { + return macro->query(it->second); + } + return true; +} + +block_builder::block_builder(const object_block *object, const macro_table *macro) +{ + m_block.name = object->name; + if (depend(object, macro)) { + m_block.type = object->type; + m_block.attr = object->attr; + for (auto i : object->data) { + if (i.second.depend.empty() || macro->query(i.second.depend)) { + m_block.data[i.first] = i.second.value; + m_strtab.push_back(i.first); + } + } + } +} + +std::string block_builder::block_tostring(const block &block) +{ + std::ostringstream ostr; + if (block.type == "map") { + ostr << map_tostring(block, block.name); + } else if (block.type == "class") { + ostr << class_tostring(block); + } else if (block.type == "vartab") { + ostr << vartab_tostring(block); + } else if (block.type == "module") { + ostr << module_tostring(block); + } + return ostr.str(); +} + +std::string block_builder::class_tostring(const block &block) +{ + bool empty_map = block.data.empty(); + std::ostringstream ostr; + hash_map map(block.data); + std::string map_name(block.name + "_map"); + + if (!empty_map) { + ostr << map_tostring(block, map_name, true) << std::endl; + } + ostr << scope(block) << " be_define_const_class(\n " + << block.name << ",\n " + << map.var_count() << ",\n " + << super(block) << ",\n " + << name(block) << "\n" + ");" << std::endl; + return ostr.str(); +} + +std::string block_builder::map_tostring(const block &block, const std::string &name, bool local) +{ + std::ostringstream ostr; + hash_map map(block.data); + + hash_map::entry_table list = map.entry_list(); + ostr << "static be_define_const_map_slots(" << name << ") {\n"; + for (auto it : list) { + ostr << " { be_const_key(" << it.key << ", " + << it.next << "), " << it.value << " }," << std::endl; + } + ostr << "};\n\n"; + + ostr << (local ? "static" : scope(block)) + << " be_define_const_map(\n " + << name << ",\n " + << list.size() << "\n" + ");" << std::endl; + return ostr.str(); +} + +std::string block_builder::vartab_tostring(const block &block) +{ + std::ostringstream ostr; + struct block idxblk; + std::vector varvec; + int index = 0; + + idxblk = block; + idxblk.data.clear(); + for (auto it : block.data) { + varvec.push_back(it.second); + it.second = "int(" + std::to_string(index++) + ")"; + idxblk.data.insert(it); + } + + ostr << map_tostring(idxblk, block.name + "_map", true) << std::endl; + ostr << "static const bvalue __vlist_array[] = {\n"; + for (auto it : varvec) { + ostr << " be_const_" << it << "," << std::endl; + } + ostr << "};\n\n"; + + ostr << "static be_define_const_vector(\n " + << block.name << "_vector,\n " + "__vlist_array,\n " + << varvec.size() << "\n" + ");" << std::endl; + return ostr.str(); +} + +std::string block_builder::module_tostring(const block &block) +{ + std::ostringstream ostr; + std::string name("m_lib" + block.name); + std::string map_name(name + "_map"); + + ostr << map_tostring(block, map_name, true) << std::endl + << "static be_define_const_module(\n " + << name << ",\n " + "\"" << block.name << "\"\n" + ");" << std::endl; + std::string scp = scope(block); + if (scp != "static") { /* extern */ + ostr << "\n" << scp + << " be_define_const_native_module(" + << block.name << ", " + << init(block) << ");" << std::endl; + } + return ostr.str(); +} + +std::string block_builder::scope(const block &block) +{ + auto it = block.attr.find("scope"); + return it != block.attr.end() && it->second == "local" ? + "static" : "BE_EXPORT_VARIABLE"; +} + +std::string block_builder::super(const block &block) +{ + auto it = block.attr.find("super"); + return it == block.attr.end() ? "NULL" : "(bclass *)&" + it->second; +} + +std::string block_builder::name(const block &block) +{ + auto it = block.attr.find("name"); + return it == block.attr.end() ? block.name : it->second; +} + +std::string block_builder::init(const block &block) +{ + auto it = block.attr.find("init"); + return it == block.attr.end() ? "NULL" : it->second; +} + +void block_builder::writefile(const std::string &filename, const std::string &text) +{ + std::string pathname(filename); + std::string otext("#include \"be_constobj.h\"\n\n" + text); + + std::ostringstream buf; + std::ifstream fin(pathname); + buf << fin.rdbuf(); + if (buf.str() != otext) { + std::ofstream fout; + fout.open(pathname, std::ios::out); + fout << otext; + fout.close(); + } +} + +void block_builder::dumpfile(const std::string &path) +{ + std::string s = block_tostring(m_block); + auto it = m_block.attr.find("file"); + std::string &name = it != m_block.attr.end() ? it->second : m_block.name; + writefile(path + "/be_fixed_" + name + ".h", s); +} + +const std::vector& block_builder::strtab() const +{ + return m_strtab; +} diff --git a/lib/libesp32/Berry/tools/coc/block_builder.h b/lib/libesp32/Berry/tools/coc/block_builder.h new file mode 100755 index 000000000..7eb82bd3e --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/block_builder.h @@ -0,0 +1,49 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __BLOCK_BUILDER_H +#define __BLOCK_BUILDER_H + +#include +#include +#include +#include "object_block.h" + +class macro_table; +class object_block; + +class block_builder { +public: + block_builder(const object_block *object, const macro_table *macro); + void dumpfile(const std::string &path); + const std::vector& strtab() const; + +private: + struct block { + std::string type; + std::string name; + std::map attr; + std::map data; + }; + + std::string block_tostring(const block &block); + std::string class_tostring(const block &block); + std::string vartab_tostring(const block &block); + std::string module_tostring(const block &block); + std::string map_tostring(const block &block, const std::string &name, bool local = false); + std::string scope(const block &block); + std::string super(const block &block); + std::string name(const block &block); + std::string init(const block &block); + void writefile(const std::string &filename, const std::string &text); + +private: + block m_block; + std::vector m_strtab; +}; + +#endif // !__BLOCK_BUILDER_H diff --git a/lib/libesp32/Berry/tools/coc/coc_parser.cpp b/lib/libesp32/Berry/tools/coc/coc_parser.cpp new file mode 100644 index 000000000..f1e86ecb5 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/coc_parser.cpp @@ -0,0 +1,189 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "coc_parser.h" +#include + +static inline int _isalnum(int c) +{ + return isalnum(c) || c == '_'; +} + +coc_parser::coc_parser(const std::string &text) +{ + m_ptr = text.c_str(); + while (*m_ptr) { + switch (*m_ptr) { + case '@': + parse_object(); + break; + case 'b': + scan_const_string(); + break; + default: + ++m_ptr; + } + } +} + +const std::vector& coc_parser::objects() const +{ + return m_objects; +} + +const std::vector& coc_parser::strtab() const +{ + return m_strtab; +} + +void coc_parser::scan_const_string() +{ + const char prefix[] = "be_const_str_"; + const size_t len = sizeof(prefix) - 1; + if (!strncmp(m_ptr, prefix, len)) { + m_ptr += len; + const char *p = m_ptr; + while (_isalnum(*m_ptr)) + ++m_ptr; + m_strtab.push_back(std::string(p, m_ptr - p)); + } else { + ++m_ptr; + } +} + +void coc_parser::skip_space() +{ + while (isspace(*m_ptr)) + ++m_ptr; +} + +bool coc_parser::parse_char_base(int c, bool necessary) +{ + bool res = *m_ptr == c; + if (!res && necessary) + throw "error"; + if (res) + ++m_ptr; + return res; +} + +bool coc_parser::parse_char(int c, bool necessary) +{ + skip_space(); + return parse_char_base(c, necessary); +} + +bool coc_parser::parse_char_continue(int c, bool necessary) +{ + int ch; + while (((ch = *m_ptr) == ' ') || ch == '\t') + ++m_ptr; + return parse_char_base(c, necessary); +} + +std::string coc_parser::parse_word() +{ + skip_space(); + const char *p = m_ptr; + if (_isalnum(*m_ptr)) { + while (_isalnum(*(++m_ptr))); + return std::string(p, m_ptr - p); + } + throw "error"; +} + +std::string coc_parser::parse_tocomma() +{ + int c; + skip_space(); + const char *p = m_ptr; + while (((c = *m_ptr) != ',') && !isspace(c)) + ++m_ptr; + if (p == m_ptr) + throw "error"; + return std::string(p, m_ptr - p); +} + +std::string coc_parser::parse_tonewline() +{ + int c; + skip_space(); + const char *p = m_ptr; + while (((c = *m_ptr) != '\r') && c != '\n') + ++m_ptr; + if (p == m_ptr) + throw "error"; + return std::string(p, m_ptr - p); +} + +void coc_parser::parse_object() +{ + const char begin_text[] = "@const_object_info_begin"; + const size_t begin_len = sizeof(begin_text) - 1; + if (!strncmp(m_ptr, begin_text, begin_len)) { + m_ptr += begin_len; + do { + object_block object; + parse_block(&object); + m_objects.push_back(object); + } while (!parse_char('@')); + const char end_text[] = "const_object_info_end"; + const size_t end_len = sizeof(end_text) - 1; + if (strncmp(m_ptr, end_text, end_len)) + throw "error"; + m_ptr += end_len; + } else { + ++m_ptr; + } +} + +void coc_parser::parse_block(object_block *object) +{ + object->type = parse_word(); + object->name = parse_word(); + parse_attr(object); + parse_body(object); +} + +void coc_parser::parse_attr(object_block *object) +{ + skip_char('('); + parse_attr_pair(object); + while (parse_char(',')) { + parse_attr_pair(object); + } + skip_char(')'); +} + +void coc_parser::parse_attr_pair(object_block *object) +{ + std::string key = parse_word(); + skip_char(':'); + std::string value = parse_word(); + object->attr[key] = value; +} + +void coc_parser::parse_body(object_block *object) +{ + skip_char('{'); + if (!parse_char('}')) { + do { + parse_body_item(object); + } while (!parse_char('}')); + } +} + +void coc_parser::parse_body_item(object_block *object) +{ + object_block::data_value value; + std::string key = parse_tocomma(); + parse_char_continue(',', true); + value.value = parse_tocomma(); + if (parse_char_continue(',')) + value.depend = parse_tonewline(); + object->data[key] = value; +} diff --git a/lib/libesp32/Berry/tools/coc/coc_parser.h b/lib/libesp32/Berry/tools/coc/coc_parser.h new file mode 100644 index 000000000..b17a68a67 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/coc_parser.h @@ -0,0 +1,46 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __COC_PARSER_H +#define __COC_PARSER_H + +#include +#include +#include "object_block.h" + +class coc_parser { +public: + coc_parser(const std::string &text); + const std::vector& objects() const; + const std::vector& strtab() const; + +private: + void scan_const_string(); + void skip_space(); + void skip_char(int c) { + parse_char(c, true); + } + bool parse_char_base(int c, bool necessary); + bool parse_char(int c, bool necessary = false); + bool parse_char_continue(int c, bool necessary = false); + std::string parse_word(); + std::string parse_tocomma(); + std::string parse_tonewline(); + void parse_object(); + void parse_block(object_block *object); + void parse_attr(object_block *object); + void parse_attr_pair(object_block *object); + void parse_body(object_block *object); + void parse_body_item(object_block *object); + +private: + const char *m_ptr; + std::vector m_objects; + std::vector m_strtab; +}; + +#endif // !__COC_PARSER_H diff --git a/lib/libesp32/Berry/tools/coc/coc_string.cpp b/lib/libesp32/Berry/tools/coc/coc_string.cpp new file mode 100644 index 000000000..1ae9384ac --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/coc_string.cpp @@ -0,0 +1,48 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "coc_string.h" +#include + +namespace coc { + +uint32_t hashcode(const std::string &string) +{ + size_t len = string.size(); + const char *str = string.data(); + uint32_t hash = 2166136261u; + while (len--) + hash = (hash ^ (unsigned char)*str++) * 16777619u; + return hash; +} + +std::string escape_operator(const std::string &string) +{ + int c = string[0]; + if (string == "..") + return "opt_connect"; + if (c == '.') + return "dot_" + string.substr(1); + if (isalpha(c) || c == '_') + return string; + const static std::map tab = { + { "+", "opt_add" }, { "-", "opt_sub" }, + { "*", "opt_mul" }, { "/", "opt_div" }, + { "%", "opt_mod" }, { "&", "opt_and" }, + { "^", "opt_xor" }, { "|", "opt_or" }, + { "<", "opt_lt" }, { ">", "opt_gt" }, + { "<=", "opt_le" }, { ">=", "opt_ge" }, + { "==", "opt_eq" }, { "!=", "opt_neq" }, + { "<<", "opt_shl" }, { ">>", "opt_shr" }, + { "-*", "opt_neg" }, { "~", "opt_flip" }, + { "()", "opt_call" } + }; + auto it = tab.find(string); + return it != tab.end() ? it->second : string; +} + +} diff --git a/lib/libesp32/Berry/tools/coc/coc_string.h b/lib/libesp32/Berry/tools/coc/coc_string.h new file mode 100644 index 000000000..5fb63ce2c --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/coc_string.h @@ -0,0 +1,18 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __COC_STRING_H +#define __COC_STRING_H + +#include + +namespace coc { + uint32_t hashcode(const std::string &string); + std::string escape_operator(const std::string &string); +} + +#endif diff --git a/lib/libesp32/Berry/tools/coc/hash_map.cpp b/lib/libesp32/Berry/tools/coc/hash_map.cpp new file mode 100755 index 000000000..988b8a03a --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/hash_map.cpp @@ -0,0 +1,161 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "hash_map.h" +#include "coc_string.h" + +#define is_empty(entry) ((entry).next == NODE_EMPTY) + +hash_map::hash_map() +{ + resize(2); +} + +hash_map::hash_map(std::map map) +{ + resize(2); + for (auto it : map) { + insert(it.first, it.second); + } +} + +hash_map::~hash_map() +{ +} + +void hash_map::resize(size_t size) +{ + entry_table bucket = m_bucket; + m_bucket.resize(size); + /* set all slot to empty */ + for (int i = 0; i < size; ++i) { + m_bucket[i].next = NODE_EMPTY; + } + m_lastfree = size - 1; + for (auto slot : bucket) { + if (!is_empty(slot)) { + insert_p(slot.key, slot.value); + } + } +} + +hash_map::entry* hash_map::findprev(entry *list, entry *slot) +{ + int next; + entry *prev = list; + for (;;) { + next = prev->next; + if (next == NODE_NULL || &m_bucket[next] == slot) { + break; + } + prev = &m_bucket[next]; + } + if (next == NODE_NULL) { + return NULL; + } + return prev; +} + +int hash_map::nextfree() +{ + while (m_lastfree >= 0) { + if (is_empty(m_bucket[m_lastfree])) { + return int(m_lastfree); + } + --m_lastfree; + } + return -1; +} + +hash_map::entry hash_map::find(const std::string &key) +{ + uint32_t hash = coc::hashcode(key); + entry null, *slot = &m_bucket[hash % m_bucket.size()]; + if (is_empty(*slot)) { + return null; + } + while (slot->key != key) { + if (slot->next == NODE_NULL) { + return null; + } + slot = &m_bucket[slot->next]; + } + return *slot; +} + +void hash_map::insert_p(const std::string &key, const std::string value) +{ + entry *slot = &m_bucket[coc::hashcode(key) % m_bucket.size()]; + if (is_empty(*slot)) { /* empty slot */ + slot->next = NODE_NULL; + } else { + int newidx = nextfree(); + /* get the main-slot index */ + entry *mainslot = &m_bucket[coc::hashcode(slot->key) % m_bucket.size()]; + entry *newslot = &m_bucket[newidx]; /* get a free slot index */ + if (mainslot == slot) { /* old is main slot */ + newslot->next = mainslot->next; + mainslot->next = newidx; + slot = newslot; + } else { /* link to list */ + entry *prev = findprev(mainslot, slot); + prev->next = newidx; /* link the previous node */ + *newslot = *slot; /* copy to new slot */ + slot->next = NODE_NULL; + } + } + slot->key = key; + slot->value = value; +} + +void hash_map::insert(const std::string &key, const std::string value) +{ + entry slot = find(key); + if (slot.next == NODE_EMPTY) { /* new entry */ + if (m_count >= m_bucket.size()) { + resize(m_bucket.size() * 2); + } + insert_p(key, value); + ++m_count; + } +} + +hash_map::entry hash_map::entry_modify(entry entry, int *var_count) +{ + entry.key = coc::escape_operator(entry.key); + if (entry.value == "var") { + entry.value = "be_const_int(" + + std::to_string(*var_count) + ")"; + ++(*var_count); + } else { + entry.value = "be_const_" + entry.value; + } + return entry; +} + +hash_map::entry_table hash_map::entry_list() +{ + entry_table list; + int var_count = 0; + + resize(m_count); + for (auto it : m_bucket) { + list.push_back(entry_modify(it, &var_count)); + } + return list; +} + +int hash_map::var_count() +{ + int count = 0; + + resize(m_count); + for (auto it : m_bucket) { + count += it.value == "var" ? 1 : 0; + } + return count; +} diff --git a/lib/libesp32/Berry/tools/coc/hash_map.h b/lib/libesp32/Berry/tools/coc/hash_map.h new file mode 100755 index 000000000..c1aca3e5b --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/hash_map.h @@ -0,0 +1,47 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __HASH_MAP +#define __HASH_MAP + +#include +#include +#include + +#define NODE_EMPTY -2 +#define NODE_NULL -1 + +class hash_map { +public: + struct entry { + std::string key; + std::string value; + int next = NODE_EMPTY; + }; + typedef std::vector entry_table; + + hash_map(); + hash_map(std::map map); + ~hash_map(); + void insert(const std::string &key, const std::string value); + hash_map::entry find(const std::string &key); + entry_table entry_list(); + int var_count(); + +private: + int nextfree(); + hash_map::entry* findprev(entry *list, entry *slot); + void resize(size_t size); + void insert_p(const std::string &key, const std::string value); + hash_map::entry entry_modify(entry entry, int *var_count); + +private: + size_t m_count = 0, m_lastfree = 0; + entry_table m_bucket; +}; + +#endif // !__HASH_MAP diff --git a/lib/libesp32/Berry/tools/coc/macro_table.cpp b/lib/libesp32/Berry/tools/coc/macro_table.cpp new file mode 100644 index 000000000..ea6d7bea7 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/macro_table.cpp @@ -0,0 +1,59 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "macro_table.h" +#include +#include +#include + +std::string macro_table::readfile(const std::string &filename) +{ + std::ifstream in(filename); + std::ostringstream tmp; + tmp << in.rdbuf(); + return tmp.str(); +} + +int macro_table::parse_value(std::string str) +{ + if (!str.length()) { + return 1; /* defined a macro name but no content, considered true */ + } + if (!(str[0] >= '0' && str[0] <= '9')) { + return 1; + } + return atoi(str.c_str()); +} + +void macro_table::scan_file(const std::string &filename) +{ + std::string str(readfile(filename)); + std::regex reg("(?:\\n|$)\\s*#define\\s+(\\w+)[ \\t]+(\\w+)"); + std::sregex_iterator it(str.begin(), str.end(), reg); + std::sregex_iterator end; + while (it != end) { + m_map[it->str(1)] = parse_value(it->str(2)); + ++it; + } +} + +bool macro_table::query(const std::string &str) const +{ + std::regex reg("(!?)(\\w+)"); + std::match_results res; + if (regex_match(str, res, reg)) { + auto it = m_map.find(res[2]); + int value = it == m_map.end() ? 0 : it->second; + return res[1] == "!" ? value == 0 : value != 0; + } + return 0; +} + +std::map macro_table::table() const +{ + return m_map; +} diff --git a/lib/libesp32/Berry/tools/coc/macro_table.h b/lib/libesp32/Berry/tools/coc/macro_table.h new file mode 100644 index 000000000..8999f63e6 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/macro_table.h @@ -0,0 +1,30 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __MACRO_TABLE_H +#define __MACRO_TABLE_H + +#include +#include +#include + +class macro_table { +public: + macro_table() {} + void scan_file(const std::string &filename); + bool query(const std::string &str) const; + std::map table() const; + +private: + std::string readfile(const std::string &filename); + int parse_value(std::string str); + +private: + std::map m_map; +}; + +#endif diff --git a/lib/libesp32/Berry/tools/coc/main.cpp b/lib/libesp32/Berry/tools/coc/main.cpp new file mode 100755 index 000000000..0b876ba65 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/main.cpp @@ -0,0 +1,141 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "main.h" +#include "block_builder.h" +#include "coc_parser.h" +#include "macro_table.h" +#include "str_build.h" +#include +#include + +void builder::parse_all(const std::string &filename) +{ + size_t pos = filename.find_last_of("."); + std::string ext = pos < filename.size() ? filename.substr(pos) : ""; + if (ext == ".c" || ext == ".cc" || ext == ".cpp") { + std::string text = readfile(filename); + coc_parser parser(text); + push_strtab(parser.strtab()); + for (auto object : parser.objects()) { + block_builder builder(&object, m_macro); + push_strtab(builder.strtab()); + builder.dumpfile(m_output); + } + } +} + +void builder::push_strtab(const std::vector &list) +{ + for (auto s : list) + m_strmap[s] = 0; +} + +std::string builder::readfile(const std::string &filename) +{ + std::ifstream in(filename); + std::ostringstream tmp; + tmp << in.rdbuf(); + return tmp.str(); +} + +#ifndef _MSC_VER +#include +#include +#include +#else +#include +#include +#endif + +#ifndef _MSC_VER +void builder::scandir(const std::string &srcpath) +{ + DIR *dp; + struct dirent *ep; + dp = opendir(srcpath.data()); + if (dp != NULL) { + while ((ep = readdir(dp)) != NULL) { + std::string fname(ep->d_name); + parse_all(srcpath + "/" + fname); + } + closedir(dp); + } +} +#else +void builder::scandir(const std::string &srcpath) +{ + HANDLE find; + WIN32_FIND_DATA data; + find = FindFirstFile((srcpath + "/*").data(), &data); + if (find != INVALID_HANDLE_VALUE) { + do { + std::string fname(data.cFileName); + parse_all(srcpath + "/" + fname); + } while (FindNextFile(find, &data) != 0); + FindClose(find); + } +} +#endif + +void builder::build() +{ + for (auto it : m_input) { + scandir(it); + } + str_build sb(m_strmap); + sb.build(m_output); +} + +builder::builder(int argc, char **argv) +{ + m_state = Input; + for (int i = 1; i < argc; ++i) { + add_arg(argv[i]); + } + m_macro = new macro_table(); + for (auto it : m_config) { + m_macro->scan_file(it); + } +} + +builder::~builder() +{ + delete m_macro; +} + +void builder::add_arg(const std::string &arg) +{ + if (arg == "-i") { + m_state = Input; + } else if (arg == "-o") { + m_state = Output; + } else if (arg == "-c") { + m_state = Config; + } else { + switch (m_state) { + case Output: + m_output = arg; + break; + case Config: + m_config.push_back(arg); + break; + case Input: + default: + m_input.push_back(arg); + break; + } + m_state = Input; + } +} + +int main(int argc, char *argv[]) +{ + builder arg(argc, argv); + arg.build(); + return 0; +} diff --git a/lib/libesp32/Berry/tools/coc/main.h b/lib/libesp32/Berry/tools/coc/main.h new file mode 100644 index 000000000..bba65d533 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/main.h @@ -0,0 +1,45 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __MAIN_H +#define __MAIN_H + +#include +#include +#include + +class macro_table; + +class builder { +public: + builder(int argc, char **argv); + ~builder(); + void build(); + +private: + void push_strtab(const std::vector& list); + void add_arg(const std::string& arg); + std::string info_block(const std::string &text); + void parse_all(const std::string &filename); + void scandir(const std::string &srcpath); + std::string readfile(const std::string &filename); + +private: + enum arg_state { + Input, + Output, + Config + }; + std::string m_output; + std::vector m_input; + std::vector m_config; + arg_state m_state; + macro_table *m_macro; + std::map m_strmap; +}; + +#endif diff --git a/lib/libesp32/Berry/tools/coc/object_block.h b/lib/libesp32/Berry/tools/coc/object_block.h new file mode 100644 index 000000000..474545457 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/object_block.h @@ -0,0 +1,25 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __OBJECT_BLOCK_H +#define __OBJECT_BLOCK_H + +#include +#include + +struct object_block { + struct data_value { + std::string value; + std::string depend; + }; + std::string type; + std::string name; + std::map attr; + std::map data; +}; + +#endif diff --git a/lib/libesp32/Berry/tools/coc/str_build.cpp b/lib/libesp32/Berry/tools/coc/str_build.cpp new file mode 100644 index 000000000..affd5016e --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/str_build.cpp @@ -0,0 +1,129 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#include "str_build.h" +#include "coc_string.h" +#include +#include + +str_build::str_build(std::map map) +{ + size_t size = map.size() / 2; + m_count = map.size(); + m_hashtable.resize(size < 4 ? 4 : size); + for (auto it : map) { + make_ceil(it.first, it.second); + } + keywords(); +} + +str_build::~str_build() +{ +} + +void str_build::build(const std::string &path) +{ + std::string prefix(path + "/be_const_strtab"); + writefile(prefix + "_def.h", build_table_def()); + writefile(prefix + ".h", build_table_ext()); +} + +void str_build::keywords() +{ + const int opif = 50; /* note the definition in be_lexer.h */ + const static std::map tab = { + { "if", opif}, { "elif", opif + 1 }, + { "else", opif + 2 }, { "while", opif + 3 }, + { "for", opif + 4 }, { "def", opif + 5 }, + { "end", opif + 6 }, { "class", opif + 7 }, + { "break", opif + 8 }, { "continue", opif + 9 }, + { "return", opif + 10 }, { "true", opif + 11 }, + { "false", opif + 12 }, { "nil", opif + 13 }, + { "var", opif + 14 }, { "do", opif + 15 }, + { "import", opif + 16 }, { "as", opif + 17 }, + { "try", opif + 18 }, { "except", opif + 19 }, + { "raise", opif + 20 } + }; + for (auto it : tab) { + make_ceil(it.first, it.second); + } +} + +void str_build::make_ceil(const std::string &string, int extra) +{ + str_info info; + info.hash = coc::hashcode(string); + info.str = string; + info.extra = extra; + m_hashtable[info.hash % m_hashtable.size()].push_back(info); +} + +void str_build::writefile(const std::string &filename, const std::string &text) +{ + std::ostringstream buf; + std::ifstream fin(filename); + buf << fin.rdbuf(); + if (buf.str() != text) { + std::ofstream fout; + fout.open(filename, std::ios::out); + fout << text; + fout.close(); + } +} + +std::string str_build::build_table_def() +{ + std::ostringstream ostr; + for (auto bucket : m_hashtable) { + size_t size = bucket.size(); + for (size_t i = 0; i < size; ++i) { + str_info info = bucket[i]; + std::string node = coc::escape_operator(info.str); + std::string next = i < size - 1 ? + "&be_const_str_" + coc::escape_operator(bucket[i + 1].str) : + "NULL"; + ostr << "be_define_const_str(" + << node << ", \"" << info.str << "\", " + << info.hash << "u, " << info.extra << ", " + << info.str.size() << ", " << next << ");" + << std::endl; + } + } + ostr << std::endl; + ostr << "static const bstring* const m_string_table[] = {" << std::endl; + size_t size = m_hashtable.size(); + for (size_t i = 0; i < size; ++i) { + auto bucket = m_hashtable[i]; + if (bucket.size()) { + ostr << " (const bstring *)&be_const_str_" + << coc::escape_operator(bucket[0].str); + } else { + ostr << " NULL"; + } + ostr << (i < size - 1 ? "," : "") << std::endl; + } + ostr << "};" << std::endl << std::endl; + ostr << + "static const struct bconststrtab m_const_string_table = {\n" + " .size = " << size << ",\n" << + " .count = " << m_count << ",\n" << + " .table = m_string_table\n" << + "};" << std::endl; + return ostr.str(); +} + +std::string str_build::build_table_ext() +{ + std::ostringstream ostr; + for (auto bucket : m_hashtable) { + for (auto info : bucket) { + ostr << "extern const bcstring be_const_str_" + << coc::escape_operator(info.str) << ";" << std::endl; + } + } + return ostr.str(); +} diff --git a/lib/libesp32/Berry/tools/coc/str_build.h b/lib/libesp32/Berry/tools/coc/str_build.h new file mode 100644 index 000000000..3a3527409 --- /dev/null +++ b/lib/libesp32/Berry/tools/coc/str_build.h @@ -0,0 +1,39 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __BUILD_MAP_H +#define __BUILD_MAP_H + +#include +#include +#include + +class str_build +{ +public: + str_build(std::map map); + ~str_build(); + void build(const std::string &path); + +private: + void keywords(); + void make_ceil(const std::string &string, int extra = 0); + std::string build_table_def(); + std::string build_table_ext(); + void writefile(const std::string &filename, const std::string &text); + +private: + struct str_info { + uint32_t hash; + std::string str; + int extra; + }; + size_t m_count; + std::vector< std::vector > m_hashtable; +}; + +#endif diff --git a/lib/libesp32/Berry/tools/grammar/berry.bytecode b/lib/libesp32/Berry/tools/grammar/berry.bytecode new file mode 100755 index 000000000..9e150635d --- /dev/null +++ b/lib/libesp32/Berry/tools/grammar/berry.bytecode @@ -0,0 +1,96 @@ +------------------------------------------------------------------------------- +-- the Berry's bytecode file structure (version 1) +-- +-- description +-- +-- a double dash ('--') start a line comment. +-- a: n means that the size of entity 'a' is 'n' bytes. +-- 'a: .n means that the size of entity 'a' is 'n' bits. +-- a: +-- b means that the entity 'a' is realized by the 'b' structure. +-- a: +-- b +-- c 'b' and 'c' are arranged in a compact order (one byte alignment). +-- [a] means that structure 'a' can be repeated 0 to any times. +-- [a](b) means that structure 'a' can be repeated 'b' times. +-- a | b means that the entity can be implemented by structure 'a' or 'b'. +-- a -> b is equivalent to 'a: +-- b'. +-- only the first entity is a file entity (the root). +------------------------------------------------------------------------------- + +bytecode_file: -- little endian + header + global_desc + main_function + +header: 8 + magic_number: 3 -- 0xbecdfe (berry code file) + version: 1 -- update with file structure definition + integer_size: .1 + float_size: .1 + -- reserved space + +main_function -> function + +global_desc: + builtin_count: 4 + global_count: 4 + global_name -> [ + string + ](global_count) + +function: + information: + function_name: + string + source: + string + argc: 1 -- arguments count + nstack: 1 -- number of stack size by this function + extra: 2 -- extra data + bytecode: + code_size: 4 + code_array -> [ -- bytecode array + instruction: 4 + ](code_size) + constant_table: + constant_count: 4 + [constant_value](constant_count) + proto_table: + proto_count: 4 + [function](proto_count) + upval_table: + upval_count: 1 + upvals -> [ + instack: 1 + index: 1 + ](upval_count) + debug_info: + -- reserved + +constant_value: + type: 1 -- type of value + integer | float | string | class + +string: + string_size: 2 + byte_array: string_size + +class: + class_name: + string + member_count: 4 -- number of member variables + method_count: 4 -- number of method + method_table -> [ + string -- method name + function -- method function body + ](method_count) + member_index_table -> [ + string -- member name + ](member_count) + +nil: 1 +boolean: 1 +integer: 4 or 8 +float: 4 or 8 diff --git a/lib/libesp32/Berry/tools/grammar/berry.ebnf b/lib/libesp32/Berry/tools/grammar/berry.ebnf new file mode 100644 index 000000000..dedf72a90 --- /dev/null +++ b/lib/libesp32/Berry/tools/grammar/berry.ebnf @@ -0,0 +1,45 @@ +(* program define *) +program = block; +(* block define *) +block = {statement}; +(* statement define *) +statement = class_stmt | func_stmt | var_stmt | if_stmt | while_stmt | + for_stmt | break_stmt | return_stmt | expr_stmt | import_stmt | + try_stmt | throw_stmt | ';'; +if_stmt = 'if' expr block {'elif' expr block} ['else' block] 'end'; +while_stmt = 'while' expr block 'end'; +for_stmt = 'for' ID ':' expr block 'end'; +break_stmt = 'break' | 'continue'; +return_stmt = 'return' [expr]; +(* function define statement *) +func_stmt = 'def' ID func_body; +func_body = '(' [arg_field {',' arg_field}] ')' block 'end'; +arg_field = ['*'] ID; +(* class define statement *) +class_stmt = 'class' ID [':' ID] class_block 'end'; +class_block = {'var' ID {',' ID} | func_stmt}; +import_stmt = 'import' (ID (['as' ID] | {',' ID}) | STRING 'as' ID); +(* exceptional handling statement *) +try_stmt = 'try' block except_block {except_block} 'end'; +except_block = except_stmt block; +except_stmt = 'except' (expr {',' expr} | '..') ['as' ID [',' ID]]; +throw_stmt = 'raise' expr [',' expr]; +(* variable define statement *) +var_stmt = 'var' ID ['=' expr] {',' ID ['=' expr]}; +(* expression define *) +expr_stmt = expr [assign_op expr]; +expr = suffix_expr | unop expr | expr binop expr | cond_expr; +cond_expr = expr '?' expr ':' expr; (* conditional expression *) +assign_op = '=' | '+=' | '-=' | '*=' | '/=' | + '%=' | '&=' | '|=' | '^=' | '<<=' | '>>='; +binop = '..' | '<' | '<=' | '==' | '!=' | '>' | '>=' | '||' | '&&' | + '<<' | '>>' | '&' | '|' | '^' | '+' | '-' | '*' | '/' | '%'; +unop = '-' | '!' | '~'; +suffix_expr = primary_expr {call_expr | ('.' ID) | '[' expr ']'}; +primary_expr = '(' expr ')' | simple_expr | list_expr | map_expr | anon_func | lambda_expr; +simple_expr = INTEGER | REAL | STRING | ID | 'true' | 'false' | 'nil'; +call_expr = '(' [expr {',' expr}] ')'; +list_expr = '[' {expr ','} [expr] ']'; +map_expr = '{' {expr ':' expr ','} [expr ':' expr] '}'; +anon_func = 'def' func_body; (* anonymous function *) +lambda_expr = '/' [arg_field {',' arg_field}] | {arg_field}] '->' expr; diff --git a/lib/libesp32/Berry/tools/grammar/const_obj.ebnf b/lib/libesp32/Berry/tools/grammar/const_obj.ebnf new file mode 100755 index 000000000..6c38a4262 --- /dev/null +++ b/lib/libesp32/Berry/tools/grammar/const_obj.ebnf @@ -0,0 +1,11 @@ +block = type name ['(' {attributes} ')'] '{' {data_fields} '}'; +type = 'map' | 'class' | 'module' | 'vartab'; + +attributes = name ':' name [',']; +data_fields = data_name ',' data_value [':' depend_macro] '\n'; + +(* regular expression *) +name = [_a-zA-Z]\w*; +data_name = [\._a-zA-Z]\w*; +data_value = [\w\()]+; +depend_macro = [_a-zA-Z]\w*; diff --git a/lib/libesp32/Berry/tools/grammar/json.ebnf b/lib/libesp32/Berry/tools/grammar/json.ebnf new file mode 100644 index 000000000..47c317193 --- /dev/null +++ b/lib/libesp32/Berry/tools/grammar/json.ebnf @@ -0,0 +1,5 @@ +json = value; +value = object | array | + string | number | 'true' | 'false' | 'null'; +object = '{' [ string ':' value ] { ',' string ':' value } '}'; +array = '[' [json] { ',' json } ']'; diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/.vsixmanifest b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/.vsixmanifest new file mode 100755 index 000000000..e14b7eabc --- /dev/null +++ b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/.vsixmanifest @@ -0,0 +1,34 @@ + + + + + Embedded Script + none + berry,Embedded Script,__ext_.berry + Languages + Public + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/CHANGELOG.md b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/CHANGELOG.md new file mode 100755 index 000000000..6f51bbcca --- /dev/null +++ b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/CHANGELOG.md @@ -0,0 +1,7 @@ +# Change Log +All notable changes to the "none" extension will be documented in this file. + +Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. + +## [Unreleased] +- Initial release \ No newline at end of file diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/README.md b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/README.md new file mode 100755 index 000000000..e69de29bb diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-configuration.json b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-configuration.json new file mode 100755 index 000000000..4be01969f --- /dev/null +++ b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-configuration.json @@ -0,0 +1,32 @@ +{ + "comments": { + // symbol used for single line comment. Remove this entry if your language does not support line comments + "lineComment": "#", + "blockComment": [ "#-", "-#" ] + }, + // symbols used as brackets + "brackets": [ + ["[", "]"], + ["(", ")"], + ["{", "}"] + ], + // symbols that are auto closed when typing + "autoClosingPairs": [ + ["[", "]"], + ["(", ")"], + ["{", "}"], + ["\"", "\""], + ["'", "'"] + ], + // symbols that that can be used to surround a selection + "surroundingPairs": [ + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ], + "indentationRules": { + "increaseIndentPattern": "(^((\\s*(class|while|for|if|elif|else|try|except))|(.*\\bdef))\\b((?!\\b(end)\\b).)*)$", + "decreaseIndentPattern": "^\\s*((\\b(elif|else|except|end)\\b)|(\\)))" + } +} \ No newline at end of file diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-icon.png b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-icon.png new file mode 100644 index 000000000..2869d5552 Binary files /dev/null and b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-icon.png differ diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/package.json b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/package.json new file mode 100755 index 000000000..8faf7e245 --- /dev/null +++ b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/package.json @@ -0,0 +1,52 @@ +{ + "name": "berry", + "displayName": "Berry Script Language", + "description": "A small embedded script language.", + "version": "0.1.0", + "icon": "berry-icon.png", + "publisher": "skiars", + "engines": { + "vscode": "^1.15.1" + }, + "categories": [ + "Programming Languages" + ], + "contributes": { + "languages": [ + { + "id": "berry", + "aliases": [ + "Berry", + "berry" + ], + "extensions": [ + ".be" + ], + "configuration": "./berry-configuration.json" + }, + { + "id": "berry-bytecode", + "aliases": [ + "Berry Bytecode", + "berry bytecode" + ], + "extensions": [ + "berry.bytecode" + ] + } + ], + "grammars": [ + { + "language": "berry", + "scopeName": "source.berry", + "path": "./syntaxes/berry.json" + }, + { + "language": "berry-bytecode", + "scopeName": "source.berry.bytecode", + "path": "./syntaxes/bytecode.json" + } + ] + }, + "__metadata": null +} \ No newline at end of file diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/berry.json b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/berry.json new file mode 100755 index 000000000..1cd1d7cfd --- /dev/null +++ b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/berry.json @@ -0,0 +1,109 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "Berry", + "patterns": [ + { + "include": "#controls" + }, + { + "include": "#strings" + }, + { + "include": "#comment-block" + }, + { + "include": "#comments" + }, + { + "include": "#keywords" + }, + { + "include": "#function" + }, + { + "include": "#member" + }, + { + "include": "#identifier" + }, + { + "include": "#number" + }, + { + "include": "#operator" + } + ], + "repository": { + "controls": { + "patterns": [{ + "name": "keyword.control.berry", + "match": "\\b(if|elif|else|for|while|do|end|break|continue|return|try|except|raise)\\b" + }] + }, + "strings": { + "patterns": [ + { + "name": "string.quoted.double.berry", + "match": "\"(\\\\.|[^\"])*\"" + }, + { + "name": "string.quoted.single.berry", + "match": "'(\\\\.|[^'])*'" + } + ] + }, + "comment-block": { + "name": "comment.berry", + "begin": "\\#\\-", + "end": "\\-#", + "patterns": [{}] + }, + "comments": { + "name": "comment.line.berry", + "begin": "\\#", + "end": "\\n", + "patterns": [{}] + }, + "keywords": { + "patterns": [{ + "name": "keyword.berry", + "match": "\\b(var|def|class|true|false|nil|self|super|import|as)\\b" + }] + }, + "identifier": { + "patterns": [{ + "name": "identifier.berry", + "match": "\\b[_A-Za-z]\\w+\\b" + }] + }, + "number": { + "patterns": [{ + "name": "constant.numeric.berry", + "match": "0x[a-fA-F0-9]+|\\d+|(\\d+\\.?|\\.\\d)\\d*([eE][+-]?\\d+)?" + }] + }, + "operator": { + "patterns": [{ + "name": "keyword.operator.berry", + "match": "\\(|\\)|\\[|\\]|\\.|-|\\!|~|\\*|/|%|\\+|&|\\^|\\||<|>|=|:" + }] + }, + "member": { + "patterns": [{ + "match": "\\.([a-zA-Z_][a-zA-Z0-9_]*)", + "captures": { + "0": { + "name": "entity.other.attribute-name.berry" + } + } + }] + }, + "function": { + "patterns": [{ + "name": "entity.name.function.berry", + "match": "\\b([a-zA-Z_][a-zA-Z0-9_]*(?=\\s*\\())" + }] + } + }, + "scopeName": "source.berry" +} \ No newline at end of file diff --git a/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/bytecode.json b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/bytecode.json new file mode 100755 index 000000000..4bd10a843 --- /dev/null +++ b/lib/libesp32/Berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/bytecode.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "Berry", + "patterns": [ + { + "include": "#comments" + }, + { + "include": "#keywords" + }, + { + "include": "#number" + }, + { + "include": "#operator" + }, + { + "include": "#entity" + } + ], + "repository": { + "comments": { + "name": "comment.line.berry.bytecode", + "begin": "\\--", + "end": "\\n", + "patterns": [{}] + }, + "keywords": { + "patterns": [{ + "name": "keyword.berry.bytecode", + "match": "or" + }] + }, + "number": { + "patterns": [{ + "name": "constant.numeric.berry.bytecode", + "match": "\\b((0x)?[0-9]+)\\b" + }] + }, + "operator": { + "patterns": [ + { + "name": "keyword.operator.berry.bytecode", + "match": "\\(|\\)|:|\\[|\\]|\\||->" + } + ] + }, + "entity": { + "patterns": [ + { + "name": "entity.name.function.berry", + "match": "^\\s*\\w+(?=\\s*(:|->))" + } + ] + } + }, + "scopeName": "source.berry.bytecode" +} \ No newline at end of file