Merge pull request #39 from ValKmjolnir/develop
👍 add regex lib & CI will pack executable in nightly build release
This commit is contained in:
commit
539e4c4964
|
@ -4,7 +4,7 @@ on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 16 * * *"
|
- cron: "0 16 * * *"
|
||||||
push:
|
push:
|
||||||
branches: [ master,develop ]
|
branches: [ master, develop ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
@ -22,6 +22,7 @@ jobs:
|
||||||
cd ..
|
cd ..
|
||||||
make test
|
make test
|
||||||
tar -czf nasal-mac-nightly.tgz .
|
tar -czf nasal-mac-nightly.tgz .
|
||||||
|
python3 tools/pack.py
|
||||||
- name: Release file
|
- name: Release file
|
||||||
# You may pin to the exact commit or the version.
|
# You may pin to the exact commit or the version.
|
||||||
# uses: djnicholson/release-action@e9a535b3eced09c460e07a84118fb74ae9b53236
|
# uses: djnicholson/release-action@e9a535b3eced09c460e07a84118fb74ae9b53236
|
||||||
|
@ -34,7 +35,9 @@ jobs:
|
||||||
# Name of the tag for the release (will be associated with current branch)
|
# Name of the tag for the release (will be associated with current branch)
|
||||||
automatic_release_tag: next_macOS
|
automatic_release_tag: next_macOS
|
||||||
# File to release
|
# File to release
|
||||||
files: nasal-mac-nightly.tgz
|
files: |
|
||||||
|
nasal-mac-nightly.tgz
|
||||||
|
nasal-Darwin.tar
|
||||||
|
|
||||||
linux-x86_64-build:
|
linux-x86_64-build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -49,6 +52,7 @@ jobs:
|
||||||
make test
|
make test
|
||||||
touch nasal-linux-x86_64-nightly.tgz
|
touch nasal-linux-x86_64-nightly.tgz
|
||||||
tar -czf nasal-linux-x86_64-nightly.tgz --exclude=nasal-linux-x86_64-nightly.tgz .
|
tar -czf nasal-linux-x86_64-nightly.tgz --exclude=nasal-linux-x86_64-nightly.tgz .
|
||||||
|
python3 tools/pack.py
|
||||||
- name: Release file
|
- name: Release file
|
||||||
# You may pin to the exact commit or the version.
|
# You may pin to the exact commit or the version.
|
||||||
# uses: djnicholson/release-action@e9a535b3eced09c460e07a84118fb74ae9b53236
|
# uses: djnicholson/release-action@e9a535b3eced09c460e07a84118fb74ae9b53236
|
||||||
|
@ -61,5 +65,7 @@ jobs:
|
||||||
# Name of the tag for the release (will be associated with current branch)
|
# Name of the tag for the release (will be associated with current branch)
|
||||||
automatic_release_tag: next_linux_x86_64
|
automatic_release_tag: next_linux_x86_64
|
||||||
# File to release
|
# File to release
|
||||||
files: nasal-linux-x86_64-nightly.tgz
|
files: |
|
||||||
|
nasal-linux-x86_64-nightly.tgz
|
||||||
|
nasal-Linux.tar
|
||||||
|
|
||||||
|
|
|
@ -19,15 +19,16 @@ set(NASAL_OBJECT_SOURCE_FILE
|
||||||
${CMAKE_SOURCE_DIR}/src/ast_dumper.cpp
|
${CMAKE_SOURCE_DIR}/src/ast_dumper.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/ast_visitor.cpp
|
${CMAKE_SOURCE_DIR}/src/ast_visitor.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/nasal_ast.cpp
|
${CMAKE_SOURCE_DIR}/src/nasal_ast.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/nasal_builtin.cpp
|
${CMAKE_SOURCE_DIR}/src/natives/nasal_builtin.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/coroutine.cpp
|
${CMAKE_SOURCE_DIR}/src/natives/coroutine.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/fg_props.cpp
|
${CMAKE_SOURCE_DIR}/src/natives/fg_props.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/bits_lib.cpp
|
${CMAKE_SOURCE_DIR}/src/natives/bits_lib.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/io_lib.cpp
|
${CMAKE_SOURCE_DIR}/src/natives/io_lib.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/json_lib.cpp
|
${CMAKE_SOURCE_DIR}/src/natives/json_lib.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/math_lib.cpp
|
${CMAKE_SOURCE_DIR}/src/natives/math_lib.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/dylib_lib.cpp
|
${CMAKE_SOURCE_DIR}/src/natives/dylib_lib.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/unix_lib.cpp
|
${CMAKE_SOURCE_DIR}/src/natives/regex_lib.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/src/natives/unix_lib.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/nasal_codegen.cpp
|
${CMAKE_SOURCE_DIR}/src/nasal_codegen.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/nasal_dbg.cpp
|
${CMAKE_SOURCE_DIR}/src/nasal_dbg.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/nasal_err.cpp
|
${CMAKE_SOURCE_DIR}/src/nasal_err.cpp
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||

|

|
||||||
[](./LICENSE)
|
[](./LICENSE)
|
||||||

|

|
||||||
|
[](https://github.com/ValKmjolnir/Nasal-Interpreter/actions/workflows/c-cpp.yml)
|
||||||
|
|
||||||
> This document is also available in: [__中文__](./doc/README_zh.md) | [__English__](./README.md)
|
> This document is also available in: [__中文__](./doc/README_zh.md) | [__English__](./README.md)
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||

|

|
||||||
[](../LICENSE)
|
[](../LICENSE)
|
||||||

|

|
||||||
|
[](https://github.com/ValKmjolnir/Nasal-Interpreter/actions/workflows/c-cpp.yml)
|
||||||
|
|
||||||
> 这篇文档包含多语言版本: [__中文__](../doc/README_zh.md) | [__English__](../README.md)
|
> 这篇文档包含多语言版本: [__中文__](../doc/README_zh.md) | [__English__](../README.md)
|
||||||
|
|
||||||
|
|
72
makefile
72
makefile
|
@ -4,16 +4,16 @@ ifndef OS
|
||||||
OS = $(shell uname)
|
OS = $(shell uname)
|
||||||
endif
|
endif
|
||||||
ifeq ($(OS), Darwin)
|
ifeq ($(OS), Darwin)
|
||||||
CXXFLAGS = -std=$(STD) -c -O3 -fno-exceptions -fPIC -mmacosx-version-min=10.15
|
CXXFLAGS = -std=$(STD) -c -O3 -fPIC -mmacosx-version-min=10.15 -I src
|
||||||
else
|
else
|
||||||
CXXFLAGS = -std=$(STD) -c -O3 -fno-exceptions -fPIC
|
CXXFLAGS = -std=$(STD) -c -O3 -fPIC -I src
|
||||||
endif
|
endif
|
||||||
|
|
||||||
NASAL_HEADER = \
|
NASAL_HEADER = \
|
||||||
src/ast_dumper.h\
|
src/ast_dumper.h\
|
||||||
src/ast_visitor.h\
|
src/ast_visitor.h\
|
||||||
src/nasal_ast.h\
|
src/nasal_ast.h\
|
||||||
src/nasal_builtin.h\
|
src/natives/nasal_builtin.h\
|
||||||
src/nasal_codegen.h\
|
src/nasal_codegen.h\
|
||||||
src/nasal_dbg.h\
|
src/nasal_dbg.h\
|
||||||
src/nasal_err.h\
|
src/nasal_err.h\
|
||||||
|
@ -27,15 +27,16 @@ NASAL_HEADER = \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/optimizer.h\
|
src/optimizer.h\
|
||||||
src/symbol_finder.h\
|
src/symbol_finder.h\
|
||||||
src/fg_props.h\
|
src/natives/fg_props.h\
|
||||||
src/bits_lib.h\
|
src/natives/bits_lib.h\
|
||||||
src/io_lib.h\
|
src/natives/io_lib.h\
|
||||||
src/math_lib.h\
|
src/natives/math_lib.h\
|
||||||
src/dylib_lib.h\
|
src/natives/dylib_lib.h\
|
||||||
src/json_lib.h\
|
src/natives/json_lib.h\
|
||||||
src/unix_lib.h\
|
src/natives/unix_lib.h\
|
||||||
src/coroutine.h\
|
src/natives/coroutine.h\
|
||||||
src/repl.h
|
src/repl.h\
|
||||||
|
src/natives/regex_lib.h
|
||||||
|
|
||||||
NASAL_OBJECT = \
|
NASAL_OBJECT = \
|
||||||
build/nasal_err.o\
|
build/nasal_err.o\
|
||||||
|
@ -64,6 +65,7 @@ NASAL_OBJECT = \
|
||||||
build/nasal_vm.o\
|
build/nasal_vm.o\
|
||||||
build/nasal_dbg.o\
|
build/nasal_dbg.o\
|
||||||
build/repl.o\
|
build/repl.o\
|
||||||
|
build/regex_lib.o\
|
||||||
build/main.o
|
build/main.o
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,72 +126,79 @@ build/nasal_builtin.o: \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/nasal_type.h\
|
src/nasal_type.h\
|
||||||
src/nasal_gc.h\
|
src/nasal_gc.h\
|
||||||
src/nasal_builtin.h src/nasal_builtin.cpp | build
|
src/natives/nasal_builtin.h src/natives/nasal_builtin.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/nasal_builtin.cpp -o build/nasal_builtin.o
|
$(CXX) $(CXXFLAGS) src/natives/nasal_builtin.cpp -o build/nasal_builtin.o
|
||||||
|
|
||||||
build/coroutine.o: \
|
build/coroutine.o: \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/nasal_type.h\
|
src/nasal_type.h\
|
||||||
src/nasal_gc.h\
|
src/nasal_gc.h\
|
||||||
src/coroutine.h src/coroutine.cpp | build
|
src/natives/coroutine.h src/natives/coroutine.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/coroutine.cpp -o build/coroutine.o
|
$(CXX) $(CXXFLAGS) src/natives/coroutine.cpp -o build/coroutine.o
|
||||||
|
|
||||||
build/bits_lib.o: \
|
build/bits_lib.o: \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/nasal_type.h\
|
src/nasal_type.h\
|
||||||
src/nasal_gc.h\
|
src/nasal_gc.h\
|
||||||
src/bits_lib.h src/bits_lib.cpp | build
|
src/natives/bits_lib.h src/natives/bits_lib.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/bits_lib.cpp -o build/bits_lib.o
|
$(CXX) $(CXXFLAGS) src/natives/bits_lib.cpp -o build/bits_lib.o
|
||||||
|
|
||||||
|
|
||||||
build/math_lib.o: \
|
build/math_lib.o: \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/nasal_type.h\
|
src/nasal_type.h\
|
||||||
src/nasal_gc.h\
|
src/nasal_gc.h\
|
||||||
src/math_lib.h src/math_lib.cpp | build
|
src/natives/math_lib.h src/natives/math_lib.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/math_lib.cpp -o build/math_lib.o
|
$(CXX) $(CXXFLAGS) src/natives/math_lib.cpp -o build/math_lib.o
|
||||||
|
|
||||||
build/io_lib.o: \
|
build/io_lib.o: \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/nasal_type.h\
|
src/nasal_type.h\
|
||||||
src/nasal_gc.h\
|
src/nasal_gc.h\
|
||||||
src/io_lib.h src/io_lib.cpp | build
|
src/natives/io_lib.h src/natives/io_lib.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/io_lib.cpp -o build/io_lib.o
|
$(CXX) $(CXXFLAGS) src/natives/io_lib.cpp -o build/io_lib.o
|
||||||
|
|
||||||
build/dylib_lib.o: \
|
build/dylib_lib.o: \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/nasal_type.h\
|
src/nasal_type.h\
|
||||||
src/nasal_gc.h\
|
src/nasal_gc.h\
|
||||||
src/dylib_lib.h src/dylib_lib.cpp | build
|
src/natives/dylib_lib.h src/natives/dylib_lib.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/dylib_lib.cpp -o build/dylib_lib.o
|
$(CXX) $(CXXFLAGS) src/natives/dylib_lib.cpp -o build/dylib_lib.o
|
||||||
|
|
||||||
build/json_lib.o: \
|
build/json_lib.o: \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/nasal_type.h\
|
src/nasal_type.h\
|
||||||
src/nasal_gc.h\
|
src/nasal_gc.h\
|
||||||
src/json_lib.h src/json_lib.cpp | build
|
src/natives/json_lib.h src/natives/json_lib.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/json_lib.cpp -o build/json_lib.o
|
$(CXX) $(CXXFLAGS) src/natives/json_lib.cpp -o build/json_lib.o
|
||||||
|
|
||||||
build/unix_lib.o: \
|
build/unix_lib.o: \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/nasal_type.h\
|
src/nasal_type.h\
|
||||||
src/nasal_gc.h\
|
src/nasal_gc.h\
|
||||||
src/unix_lib.h src/unix_lib.cpp | build
|
src/natives/unix_lib.h src/natives/unix_lib.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/unix_lib.cpp -o build/unix_lib.o
|
$(CXX) $(CXXFLAGS) src/natives/unix_lib.cpp -o build/unix_lib.o
|
||||||
|
|
||||||
|
build/regex_lib.o: \
|
||||||
|
src/nasal.h\
|
||||||
|
src/nasal_type.h\
|
||||||
|
src/nasal_gc.h\
|
||||||
|
src/natives/regex_lib.h src/natives/regex_lib.cpp | build
|
||||||
|
$(CXX) $(CXXFLAGS) src/natives/regex_lib.cpp -o build/regex_lib.o
|
||||||
|
|
||||||
build/fg_props.o: \
|
build/fg_props.o: \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/nasal_type.h\
|
src/nasal_type.h\
|
||||||
src/nasal_gc.h\
|
src/nasal_gc.h\
|
||||||
src/fg_props.h src/fg_props.cpp | build
|
src/natives/fg_props.h src/natives/fg_props.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/fg_props.cpp -o build/fg_props.o
|
$(CXX) $(CXXFLAGS) src/natives/fg_props.cpp -o build/fg_props.o
|
||||||
|
|
||||||
build/nasal_codegen.o: $(NASAL_HEADER) src/nasal_codegen.h src/nasal_codegen.cpp | build
|
build/nasal_codegen.o: $(NASAL_HEADER) src/nasal_codegen.h src/nasal_codegen.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/nasal_codegen.cpp -o build/nasal_codegen.o
|
$(CXX) $(CXXFLAGS) src/nasal_codegen.cpp -o build/nasal_codegen.o
|
||||||
|
|
||||||
build/nasal_opcode.o: \
|
build/nasal_opcode.o: \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/nasal_builtin.h\
|
src/natives/nasal_builtin.h\
|
||||||
src/nasal_opcode.h src/nasal_opcode.cpp | build
|
src/nasal_opcode.h src/nasal_opcode.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/nasal_opcode.cpp -o build/nasal_opcode.o
|
$(CXX) $(CXXFLAGS) src/nasal_opcode.cpp -o build/nasal_opcode.o
|
||||||
|
|
||||||
|
@ -279,6 +288,7 @@ test:nasal
|
||||||
@ ./nasal -t -d test/prime.nas
|
@ ./nasal -t -d test/prime.nas
|
||||||
@ ./nasal -e test/qrcode.nas
|
@ ./nasal -e test/qrcode.nas
|
||||||
@ ./nasal -t -d test/quick_sort.nas
|
@ ./nasal -t -d test/quick_sort.nas
|
||||||
|
@ ./nasal -t -d test/regex_test.nas
|
||||||
@ ./nasal -e test/scalar.nas hello world
|
@ ./nasal -e test/scalar.nas hello world
|
||||||
@ ./nasal -e test/trait.nas
|
@ ./nasal -e test/trait.nas
|
||||||
@ ./nasal -t -d test/turingmachine.nas
|
@ ./nasal -t -d test/turingmachine.nas
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
// load socket library on windows platform
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
#pragma comment(lib,"ws2_32")
|
#pragma comment(lib,"ws2_32")
|
||||||
|
|
||||||
|
@ -25,8 +26,9 @@ public:
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// use static object to do WSAStartup and WSACleanup
|
||||||
static WSAmanager win;
|
static WSAmanager win;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
|
@ -68,7 +68,7 @@ public:
|
||||||
const char* c_str() const {
|
const char* c_str() const {
|
||||||
return file_system_path.c_str();
|
return file_system_path.c_str();
|
||||||
}
|
}
|
||||||
std::string str() const {
|
const std::string& str() const {
|
||||||
return file_system_path;
|
return file_system_path;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
||||||
enum class expr_type:u32 {
|
enum class expr_type: u32 {
|
||||||
ast_null = 0, // null node
|
ast_null = 0, // null node
|
||||||
ast_use, // use statement
|
ast_use, // use statement
|
||||||
ast_block, // code block
|
ast_block, // code block
|
||||||
|
|
|
@ -37,6 +37,7 @@ void codegen::init_native_function() {
|
||||||
load_native_function_table(dylib_lib_native);
|
load_native_function_table(dylib_lib_native);
|
||||||
load_native_function_table(unix_lib_native);
|
load_native_function_table(unix_lib_native);
|
||||||
load_native_function_table(json_lib_native);
|
load_native_function_table(json_lib_native);
|
||||||
|
load_native_function_table(regex_lib_native);
|
||||||
}
|
}
|
||||||
|
|
||||||
void codegen::check_id_exist(identifier* node) {
|
void codegen::check_id_exist(identifier* node) {
|
||||||
|
|
|
@ -8,15 +8,16 @@
|
||||||
#include "nasal_parse.h"
|
#include "nasal_parse.h"
|
||||||
#include "nasal_import.h"
|
#include "nasal_import.h"
|
||||||
|
|
||||||
#include "nasal_builtin.h"
|
#include "natives/nasal_builtin.h"
|
||||||
#include "coroutine.h"
|
#include "natives/coroutine.h"
|
||||||
#include "bits_lib.h"
|
#include "natives/bits_lib.h"
|
||||||
#include "math_lib.h"
|
#include "natives/math_lib.h"
|
||||||
#include "fg_props.h"
|
#include "natives/fg_props.h"
|
||||||
#include "io_lib.h"
|
#include "natives/io_lib.h"
|
||||||
#include "json_lib.h"
|
#include "natives/json_lib.h"
|
||||||
#include "dylib_lib.h"
|
#include "natives/dylib_lib.h"
|
||||||
#include "unix_lib.h"
|
#include "natives/regex_lib.h"
|
||||||
|
#include "natives/unix_lib.h"
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -36,9 +37,11 @@ private:
|
||||||
error err;
|
error err;
|
||||||
|
|
||||||
// repl output flag, will generate op_repl to output stack top value if true
|
// repl output flag, will generate op_repl to output stack top value if true
|
||||||
bool need_repl_output;
|
bool need_repl_output = false;
|
||||||
|
|
||||||
// limit mode flag
|
// limit mode flag
|
||||||
bool flag_limited_mode;
|
bool flag_limited_mode = false;
|
||||||
|
// under limited mode, unsafe system api will be banned
|
||||||
const std::unordered_set<std::string> unsafe_system_api = {
|
const std::unordered_set<std::string> unsafe_system_api = {
|
||||||
// builtin
|
// builtin
|
||||||
"__system", "__input",
|
"__system", "__input",
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
||||||
void debug_prof_data::init_counter() {
|
void operand_line_counter::init_counter() {
|
||||||
for(usize i = 0; i<debug_prof_data::operand_size; ++i) {
|
for(usize i = 0; i<operand_line_counter::operand_size; ++i) {
|
||||||
operand_counter[i] = 0;
|
operand_counter[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug_prof_data::load_file_line_counter(
|
void operand_line_counter::load_file_line_counter(
|
||||||
const std::vector<std::string>& file_list) {
|
const std::vector<std::string>& file_list) {
|
||||||
file_name_list = file_list;
|
file_name_list = file_list;
|
||||||
file_line_counter = {};
|
file_line_counter = {};
|
||||||
|
@ -22,16 +22,16 @@ void debug_prof_data::load_file_line_counter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug_prof_data::init(const std::vector<std::string>& file_list) {
|
void operand_line_counter::init(const std::vector<std::string>& file_list) {
|
||||||
init_counter();
|
init_counter();
|
||||||
load_file_line_counter(file_list);
|
load_file_line_counter(file_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug_prof_data::dump_counter() const {
|
void operand_line_counter::dump_operand_count() const {
|
||||||
typedef std::pair<u32, u64> op_count;
|
typedef std::pair<u32, u64> op_count;
|
||||||
std::vector<op_count> opcall;
|
std::vector<op_count> opcall;
|
||||||
u64 total = 0;
|
u64 total = 0;
|
||||||
for(usize i = 0; i<debug_prof_data::operand_size; ++i) {
|
for(usize i = 0; i<operand_line_counter::operand_size; ++i) {
|
||||||
total += operand_counter[i];
|
total += operand_counter[i];
|
||||||
opcall.push_back({i, operand_counter[i]});
|
opcall.push_back({i, operand_counter[i]});
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ void debug_prof_data::dump_counter() const {
|
||||||
std::clog << " total : " << total << '\n';
|
std::clog << " total : " << total << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug_prof_data::dump_code_line_counter(std::ostream& os) const {
|
void operand_line_counter::dump_all_code_line_counter(std::ostream& os) const {
|
||||||
u64 max_call_time = 0;
|
u64 max_call_time = 0;
|
||||||
for(const auto& context : file_line_counter) {
|
for(const auto& context : file_line_counter) {
|
||||||
for(const auto& count : context) {
|
for(const auto& count : context) {
|
||||||
|
@ -73,7 +73,7 @@ void debug_prof_data::dump_code_line_counter(std::ostream& os) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug_prof_data::dump_this_file_line_counter(std::ostream& os) const {
|
void operand_line_counter::dump_this_file_line_counter(std::ostream& os) const {
|
||||||
u64 max_call_time = 0;
|
u64 max_call_time = 0;
|
||||||
for(const auto& count : file_line_counter[0]) {
|
for(const auto& count : file_line_counter[0]) {
|
||||||
max_call_time = count>max_call_time? count:max_call_time;
|
max_call_time = count>max_call_time? count:max_call_time;
|
||||||
|
@ -178,7 +178,7 @@ void dbg::interact() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not need interact while doing profiling
|
// do not need interact while doing profiling
|
||||||
if (do_profiling) {
|
if (do_operand_count) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,24 +199,24 @@ void dbg::interact() {
|
||||||
step_info();
|
step_info();
|
||||||
} else if (res.size()==1) {
|
} else if (res.size()==1) {
|
||||||
switch(get_cmd_type(res[0])) {
|
switch(get_cmd_type(res[0])) {
|
||||||
case dbg_cmd::cmd_help: help(); break;
|
case cmd_kind::cmd_help: help(); break;
|
||||||
case dbg_cmd::cmd_backtrace:
|
case cmd_kind::cmd_backtrace:
|
||||||
function_call_trace();
|
function_call_trace();
|
||||||
trace_back();
|
trace_back();
|
||||||
break;
|
break;
|
||||||
case dbg_cmd::cmd_continue: return;
|
case cmd_kind::cmd_continue: return;
|
||||||
case dbg_cmd::cmd_list_file: list_file(); break;
|
case cmd_kind::cmd_list_file: list_file(); break;
|
||||||
case dbg_cmd::cmd_global: global_state(); break;
|
case cmd_kind::cmd_global: global_state(); break;
|
||||||
case dbg_cmd::cmd_local: local_state(); break;
|
case cmd_kind::cmd_local: local_state(); break;
|
||||||
case dbg_cmd::cmd_upval: upvalue_state(); break;
|
case cmd_kind::cmd_upval: upvalue_state(); break;
|
||||||
case dbg_cmd::cmd_register: register_info(); break;
|
case cmd_kind::cmd_register: register_info(); break;
|
||||||
case dbg_cmd::cmd_show_all: all_state_detail(); break;
|
case cmd_kind::cmd_show_all: all_state_detail(); break;
|
||||||
case dbg_cmd::cmd_next: next = true; return;
|
case cmd_kind::cmd_next: next = true; return;
|
||||||
case dbg_cmd::cmd_exit: std::exit(0);
|
case cmd_kind::cmd_exit: std::exit(0);
|
||||||
default: err(); break;
|
default: err(); break;
|
||||||
}
|
}
|
||||||
} else if (res.size()==3 &&
|
} else if (res.size()==3 &&
|
||||||
get_cmd_type(res[0])==dbg_cmd::cmd_break_point) {
|
get_cmd_type(res[0])==cmd_kind::cmd_break_point) {
|
||||||
break_file_index = file_index(res[1]);
|
break_file_index = file_index(res[1]);
|
||||||
if (break_file_index==65535) {
|
if (break_file_index==65535) {
|
||||||
std::clog << "cannot find file named `" << res[1] << "`\n";
|
std::clog << "cannot find file named `" << res[1] << "`\n";
|
||||||
|
@ -242,7 +242,7 @@ void dbg::run(
|
||||||
bool show_all_prof_result) {
|
bool show_all_prof_result) {
|
||||||
|
|
||||||
set_detail_report_info(true);
|
set_detail_report_info(true);
|
||||||
do_profiling = profile || show_all_prof_result;
|
do_operand_count = profile || show_all_prof_result;
|
||||||
|
|
||||||
const auto& file_list = linker.get_file_list();
|
const auto& file_list = linker.get_file_list();
|
||||||
fsize = file_list.size();
|
fsize = file_list.size();
|
||||||
|
@ -255,7 +255,7 @@ void dbg::run(
|
||||||
file_list,
|
file_list,
|
||||||
argv
|
argv
|
||||||
);
|
);
|
||||||
data.init(file_list);
|
counter.init(file_list);
|
||||||
|
|
||||||
std::vector<u32> code;
|
std::vector<u32> code;
|
||||||
std::vector<u16> code_file_index;
|
std::vector<u16> code_file_index;
|
||||||
|
@ -268,8 +268,8 @@ void dbg::run(
|
||||||
}
|
}
|
||||||
while(operand_function[code[ctx.pc]]) {
|
while(operand_function[code[ctx.pc]]) {
|
||||||
interact();
|
interact();
|
||||||
data.add_operand_counter(code[ctx.pc]);
|
counter.add_operand_counter(code[ctx.pc]);
|
||||||
data.add_code_line_counter(code_file_index[ctx.pc], code_line[ctx.pc]);
|
counter.add_code_line_counter(code_file_index[ctx.pc], code_line[ctx.pc]);
|
||||||
(this->*operand_function[code[ctx.pc]])();
|
(this->*operand_function[code[ctx.pc]])();
|
||||||
if (ctx.top>=ctx.canary) {
|
if (ctx.top>=ctx.canary) {
|
||||||
die("stack overflow");
|
die("stack overflow");
|
||||||
|
@ -277,11 +277,11 @@ void dbg::run(
|
||||||
++ctx.pc;
|
++ctx.pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.dump_counter();
|
counter.dump_operand_count();
|
||||||
if (do_profiling) {
|
if (do_operand_count) {
|
||||||
show_all_prof_result?
|
show_all_prof_result?
|
||||||
data.dump_code_line_counter(std::clog):
|
counter.dump_all_code_line_counter(std::clog):
|
||||||
data.dump_this_file_line_counter(std::clog);
|
counter.dump_this_file_line_counter(std::clog);
|
||||||
}
|
}
|
||||||
ngc.info();
|
ngc.info();
|
||||||
ngc.clear();
|
ngc.clear();
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
||||||
class debug_prof_data {
|
// count detail operand calling
|
||||||
|
// and show them before each line of the source file
|
||||||
|
class operand_line_counter {
|
||||||
private:
|
private:
|
||||||
static const usize operand_size = op_code_type::op_ret + 1;
|
static const usize operand_size = op_code_type::op_ret + 1;
|
||||||
u64 operand_counter[operand_size];
|
u64 operand_counter[operand_size];
|
||||||
|
@ -25,8 +27,8 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void init(const std::vector<std::string>&);
|
void init(const std::vector<std::string>&);
|
||||||
void dump_counter() const;
|
void dump_operand_count() const;
|
||||||
void dump_code_line_counter(std::ostream&) const;
|
void dump_all_code_line_counter(std::ostream&) const;
|
||||||
void dump_this_file_line_counter(std::ostream&) const;
|
void dump_this_file_line_counter(std::ostream&) const;
|
||||||
void add_operand_counter(usize index) {
|
void add_operand_counter(usize index) {
|
||||||
operand_counter[index] += index<operand_size? 1:0;
|
operand_counter[index] += index<operand_size? 1:0;
|
||||||
|
@ -88,7 +90,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class dbg_cmd {
|
enum class cmd_kind {
|
||||||
cmd_error,
|
cmd_error,
|
||||||
cmd_help,
|
cmd_help,
|
||||||
cmd_backtrace,
|
cmd_backtrace,
|
||||||
|
@ -105,35 +107,35 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::unordered_map<std::string, dbg_cmd> command_table = {
|
const std::unordered_map<std::string, cmd_kind> command_table = {
|
||||||
{"h", dbg_cmd::cmd_help},
|
{"h", cmd_kind::cmd_help},
|
||||||
{"help", dbg_cmd::cmd_help},
|
{"help", cmd_kind::cmd_help},
|
||||||
{"bt", dbg_cmd::cmd_backtrace},
|
{"bt", cmd_kind::cmd_backtrace},
|
||||||
{"backtrace", dbg_cmd::cmd_backtrace},
|
{"backtrace", cmd_kind::cmd_backtrace},
|
||||||
{"c", dbg_cmd::cmd_continue},
|
{"c", cmd_kind::cmd_continue},
|
||||||
{"continue", dbg_cmd::cmd_continue},
|
{"continue", cmd_kind::cmd_continue},
|
||||||
{"f", dbg_cmd::cmd_list_file},
|
{"f", cmd_kind::cmd_list_file},
|
||||||
{"file", dbg_cmd::cmd_list_file},
|
{"file", cmd_kind::cmd_list_file},
|
||||||
{"g", dbg_cmd::cmd_global},
|
{"g", cmd_kind::cmd_global},
|
||||||
{"global", dbg_cmd::cmd_global},
|
{"global", cmd_kind::cmd_global},
|
||||||
{"l", dbg_cmd::cmd_local},
|
{"l", cmd_kind::cmd_local},
|
||||||
{"local", dbg_cmd::cmd_local},
|
{"local", cmd_kind::cmd_local},
|
||||||
{"u", dbg_cmd::cmd_upval},
|
{"u", cmd_kind::cmd_upval},
|
||||||
{"upval", dbg_cmd::cmd_upval},
|
{"upval", cmd_kind::cmd_upval},
|
||||||
{"r", dbg_cmd::cmd_register},
|
{"r", cmd_kind::cmd_register},
|
||||||
{"register", dbg_cmd::cmd_register},
|
{"register", cmd_kind::cmd_register},
|
||||||
{"a", dbg_cmd::cmd_show_all},
|
{"a", cmd_kind::cmd_show_all},
|
||||||
{"all", dbg_cmd::cmd_show_all},
|
{"all", cmd_kind::cmd_show_all},
|
||||||
{"n", dbg_cmd::cmd_next},
|
{"n", cmd_kind::cmd_next},
|
||||||
{"next", dbg_cmd::cmd_next},
|
{"next", cmd_kind::cmd_next},
|
||||||
{"bk", dbg_cmd::cmd_break_point},
|
{"bk", cmd_kind::cmd_break_point},
|
||||||
{"break", dbg_cmd::cmd_break_point},
|
{"break", cmd_kind::cmd_break_point},
|
||||||
{"q", dbg_cmd::cmd_exit},
|
{"q", cmd_kind::cmd_exit},
|
||||||
{"exit", dbg_cmd::cmd_exit}
|
{"exit", cmd_kind::cmd_exit}
|
||||||
};
|
};
|
||||||
dbg_cmd get_cmd_type(const std::string& cmd) const {
|
cmd_kind get_cmd_type(const std::string& cmd) const {
|
||||||
return command_table.count(cmd)?
|
return command_table.count(cmd)?
|
||||||
command_table.at(cmd):dbg_cmd::cmd_error;
|
command_table.at(cmd):cmd_kind::cmd_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -144,8 +146,8 @@ private:
|
||||||
error src;
|
error src;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
debug_prof_data data;
|
operand_line_counter counter;
|
||||||
bool do_profiling;
|
bool do_operand_count;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> parse(const std::string&);
|
std::vector<std::string> parse(const std::string&);
|
||||||
|
@ -160,7 +162,7 @@ public:
|
||||||
dbg():
|
dbg():
|
||||||
next(true), fsize(0),
|
next(true), fsize(0),
|
||||||
break_file_index(0), break_line(0),
|
break_file_index(0), break_line(0),
|
||||||
do_profiling(false) {}
|
do_operand_count(false) {}
|
||||||
void run(
|
void run(
|
||||||
const codegen&,
|
const codegen&,
|
||||||
const linker&,
|
const linker&,
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
#include "nasal_builtin.h"
|
#include "natives/nasal_builtin.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
||||||
enum op_code_type:u8 {
|
enum op_code_type: u8 {
|
||||||
op_exit, // stop the virtual machine
|
op_exit, // stop the virtual machine
|
||||||
op_repl, // in repl mode: print value on stack top
|
op_repl, // in repl mode: print value on stack top
|
||||||
op_intl, // local scope size
|
op_intl, // local scope size
|
||||||
|
|
|
@ -58,7 +58,7 @@ void parse::easter_egg() {
|
||||||
<< " `\"` `\"` \n";
|
<< " `\"` `\"` \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse::die(const span& loc, std::string info) {
|
void parse::die(const span& loc, const std::string& info) {
|
||||||
err.err("parse", loc, info);
|
err.err("parse", loc, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,9 +79,9 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void die(const span&,std::string);
|
void die(const span&, const std::string&);
|
||||||
void next();
|
void next();
|
||||||
void match(tok, const char* info=nullptr);
|
void match(tok, const char* info = nullptr);
|
||||||
bool lookahead(tok);
|
bool lookahead(tok);
|
||||||
bool is_call(tok);
|
bool is_call(tok);
|
||||||
bool check_comma(const tok*);
|
bool check_comma(const tok*);
|
||||||
|
|
|
@ -249,7 +249,7 @@ std::string var::to_str() {
|
||||||
if (type==vm_type::vm_str) {
|
if (type==vm_type::vm_str) {
|
||||||
return str();
|
return str();
|
||||||
} else if (type==vm_type::vm_num) {
|
} else if (type==vm_type::vm_num) {
|
||||||
std::string tmp = std::to_string(num());
|
auto tmp = std::to_string(num());
|
||||||
tmp.erase(tmp.find_last_not_of('0')+1, std::string::npos);
|
tmp.erase(tmp.find_last_not_of('0')+1, std::string::npos);
|
||||||
tmp.erase(tmp.find_last_not_of('.')+1, std::string::npos);
|
tmp.erase(tmp.find_last_not_of('.')+1, std::string::npos);
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|
|
@ -414,10 +414,16 @@ void vm::die(const std::string& str) {
|
||||||
void vm::run(
|
void vm::run(
|
||||||
const codegen& gen,
|
const codegen& gen,
|
||||||
const linker& linker,
|
const linker& linker,
|
||||||
const std::vector<std::string>& argv
|
const std::vector<std::string>& argv) {
|
||||||
) {
|
init(
|
||||||
init(gen.strs(), gen.nums(), gen.natives(),
|
gen.strs(),
|
||||||
gen.codes(), gen.globals(), linker.get_file_list(), argv);
|
gen.nums(),
|
||||||
|
gen.natives(),
|
||||||
|
gen.codes(),
|
||||||
|
gen.globals(),
|
||||||
|
linker.get_file_list(),
|
||||||
|
argv
|
||||||
|
);
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
// using labels as values/computed goto
|
// using labels as values/computed goto
|
||||||
const void* oprs[] = {
|
const void* oprs[] = {
|
||||||
|
|
|
@ -21,7 +21,7 @@ class vm {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* registers of vm */
|
/* registers of vm */
|
||||||
context ctx;
|
context ctx; // running context
|
||||||
|
|
||||||
/* constants */
|
/* constants */
|
||||||
const f64* const_number = nullptr; // constant numbers
|
const f64* const_number = nullptr; // constant numbers
|
||||||
|
@ -33,8 +33,8 @@ protected:
|
||||||
gc ngc;
|
gc ngc;
|
||||||
|
|
||||||
/* main stack */
|
/* main stack */
|
||||||
var* global = nullptr;
|
var* global = nullptr; // used to store global variables
|
||||||
usize global_size = 0;
|
usize global_size = 0; // mark size of global variables
|
||||||
|
|
||||||
/* values used for debugger */
|
/* values used for debugger */
|
||||||
const std::string* files = nullptr; // file name list
|
const std::string* files = nullptr; // file name list
|
||||||
|
@ -45,7 +45,7 @@ protected:
|
||||||
bool first_exec_flag = true;
|
bool first_exec_flag = true;
|
||||||
bool allow_repl_output = false;
|
bool allow_repl_output = false;
|
||||||
|
|
||||||
/* limited mode, will not load unsafe system api if switch on */
|
/* limited mode, will not load unsafe system api if switched on */
|
||||||
bool flag_limited_mode = false;
|
bool flag_limited_mode = false;
|
||||||
|
|
||||||
/* vm initializing function */
|
/* vm initializing function */
|
||||||
|
@ -184,9 +184,9 @@ public:
|
||||||
|
|
||||||
/* execution entry */
|
/* execution entry */
|
||||||
void run(
|
void run(
|
||||||
const codegen&,
|
const codegen&, // get generated code
|
||||||
const linker&,
|
const linker&, // get list of used files
|
||||||
const std::vector<std::string>&
|
const std::vector<std::string>& // get arguments input by command line
|
||||||
);
|
);
|
||||||
|
|
||||||
/* set detail report info flag */
|
/* set detail report info flag */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "bits_lib.h"
|
#include "natives/bits_lib.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
#include "nasal_gc.h"
|
#include "nasal_gc.h"
|
||||||
#include "nasal_builtin.h"
|
#include "natives/nasal_builtin.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "coroutine.h"
|
#include "natives/coroutine.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
#include "nasal_gc.h"
|
#include "nasal_gc.h"
|
||||||
#include "nasal_builtin.h"
|
#include "natives/nasal_builtin.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "dylib_lib.h"
|
#include "natives/dylib_lib.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
#include "nasal_gc.h"
|
#include "nasal_gc.h"
|
||||||
#include "nasal_builtin.h"
|
#include "natives/nasal_builtin.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
|
@ -1,4 +1,4 @@
|
||||||
#include "fg_props.h"
|
#include "natives/fg_props.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
#include "nasal_gc.h"
|
#include "nasal_gc.h"
|
||||||
#include "nasal_builtin.h"
|
#include "natives/nasal_builtin.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "io_lib.h"
|
#include "natives/io_lib.h"
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
#include "nasal_gc.h"
|
#include "nasal_gc.h"
|
||||||
#include "nasal_builtin.h"
|
#include "natives/nasal_builtin.h"
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
|
@ -1,4 +1,4 @@
|
||||||
#include "json_lib.h"
|
#include "natives/json_lib.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
#include "nasal_gc.h"
|
#include "nasal_gc.h"
|
||||||
#include "nasal_builtin.h"
|
#include "natives/nasal_builtin.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "math_lib.h"
|
#include "natives/math_lib.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
#include "nasal_gc.h"
|
#include "nasal_gc.h"
|
||||||
#include "nasal_builtin.h"
|
#include "natives/nasal_builtin.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "nasal_builtin.h"
|
#include "natives/nasal_builtin.h"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include "natives/regex_lib.h"
|
||||||
|
|
||||||
|
namespace nasal {
|
||||||
|
|
||||||
|
var builtin_regex_match(context* ctx, gc* ngc) {
|
||||||
|
auto source = ctx->localr[1];
|
||||||
|
auto reg_str = ctx->localr[2];
|
||||||
|
if (!source.is_str()) {
|
||||||
|
return nas_err("regex::match", "\"src\" must be a string");
|
||||||
|
}
|
||||||
|
if (!reg_str.is_str()) {
|
||||||
|
return nas_err("regex::match", "\"reg\" must be a format string");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
auto res = std::regex_match(source.str(), std::regex(reg_str.str()));
|
||||||
|
return res? one:zero;
|
||||||
|
} catch(const std::regex_error& e) {
|
||||||
|
return nas_err("regex::match", e.what());
|
||||||
|
}
|
||||||
|
return zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
var builtin_regex_search(context* ctx, gc* ngc) {
|
||||||
|
auto source = ctx->localr[1];
|
||||||
|
auto reg_str = ctx->localr[2];
|
||||||
|
if (!source.is_str()) {
|
||||||
|
return nas_err("regex::search", "\"src\" must be a string");
|
||||||
|
}
|
||||||
|
if (!reg_str.is_str()) {
|
||||||
|
return nas_err("regex::search", "\"reg\" must be a format string");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
auto res = std::regex_search(source.str(), std::regex(reg_str.str()));
|
||||||
|
return res? one:zero;
|
||||||
|
} catch(const std::regex_error& e) {
|
||||||
|
return nas_err("regex::search", e.what());
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
var builtin_regex_replace(context* ctx, gc* ngc) {
|
||||||
|
auto source = ctx->localr[1];
|
||||||
|
auto reg_str = ctx->localr[2];
|
||||||
|
auto fmt = ctx->localr[3];
|
||||||
|
if (!source.is_str()) {
|
||||||
|
return nas_err("regex::replace", "\"src\" must be a string");
|
||||||
|
}
|
||||||
|
if (!reg_str.is_str()) {
|
||||||
|
return nas_err("regex::replace", "\"reg\" must be a format string");
|
||||||
|
}
|
||||||
|
if (!fmt.is_str()) {
|
||||||
|
return nas_err("regex::replace", "\"fmt\" must be a format string");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
auto res = std::regex_replace(
|
||||||
|
source.str(),
|
||||||
|
std::regex(reg_str.str()),
|
||||||
|
fmt.str()
|
||||||
|
);
|
||||||
|
return ngc->newstr(res);
|
||||||
|
} catch(const std::regex_error& e) {
|
||||||
|
return nas_err("regex::replace", e.what());
|
||||||
|
}
|
||||||
|
return ngc->newstr(source.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
var builtin_regex_match_all(context* ctx, gc* ngc) {
|
||||||
|
auto source = ctx->localr[1];
|
||||||
|
auto reg_str = ctx->localr[2];
|
||||||
|
if (!source.is_str()) {
|
||||||
|
return nas_err("regex::match_all", "\"src\" must be a string");
|
||||||
|
}
|
||||||
|
if (!reg_str.is_str()) {
|
||||||
|
return nas_err("regex::match_all", "\"reg\" must be a format string");
|
||||||
|
}
|
||||||
|
auto res = ngc->temp = ngc->alloc(vm_type::vm_vec);
|
||||||
|
try {
|
||||||
|
const auto& src = source.str();
|
||||||
|
auto words_regex = std::regex(reg_str.str());
|
||||||
|
auto begin = std::sregex_iterator(src.begin(), src.end(), words_regex);
|
||||||
|
auto end = std::sregex_iterator();
|
||||||
|
for (auto i = begin; i!=end; ++i) {
|
||||||
|
res.vec().elems.push_back(ngc->newstr((*i).str()));
|
||||||
|
}
|
||||||
|
} catch(const std::regex_error& e) {
|
||||||
|
return nas_err("regex::match_all", e.what());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
nasal_builtin_table regex_lib_native[] = {
|
||||||
|
{"__regex_match", builtin_regex_match},
|
||||||
|
{"__regex_search", builtin_regex_search},
|
||||||
|
{"__regex_replace", builtin_regex_replace},
|
||||||
|
{"__regex_match_all", builtin_regex_match_all},
|
||||||
|
{nullptr, nullptr}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include "nasal.h"
|
||||||
|
#include "nasal_gc.h"
|
||||||
|
#include "natives/nasal_builtin.h"
|
||||||
|
|
||||||
|
namespace nasal {
|
||||||
|
|
||||||
|
var builtin_regex_match(context*, gc*);
|
||||||
|
var builtin_regex_search(context*, gc*);
|
||||||
|
var builtin_regex_replace(context*, gc*);
|
||||||
|
var builtin_regex_match_all(context*, gc*);
|
||||||
|
|
||||||
|
extern nasal_builtin_table regex_lib_native[];
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
#include "unix_lib.h"
|
#include "natives/unix_lib.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
#include "nasal_gc.h"
|
#include "nasal_gc.h"
|
||||||
#include "nasal_builtin.h"
|
#include "natives/nasal_builtin.h"
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
||||||
|
// experimental optimizer for constant calculation
|
||||||
class optimizer: public ast_visitor {
|
class optimizer: public ast_visitor {
|
||||||
private:
|
private:
|
||||||
void const_string(binary_operator*, string_literal*, string_literal*);
|
void const_string(binary_operator*, string_literal*, string_literal*);
|
||||||
|
|
|
@ -19,10 +19,10 @@ void repl::add_command_history(const std::string& history) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string repl::readline(std::string prompt = ">>> ") {
|
std::string repl::readline(const std::string& prompt = ">>> ") {
|
||||||
auto line = std::string("");
|
auto line = std::string("");
|
||||||
std::cout << prompt;
|
std::cout << prompt;
|
||||||
std::getline(std::cin, line,'\n');
|
std::getline(std::cin, line, '\n');
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void add_command_history(const std::string&);
|
void add_command_history(const std::string&);
|
||||||
std::string readline(std::string);
|
std::string readline(const std::string&);
|
||||||
bool check_need_more_input();
|
bool check_need_more_input();
|
||||||
void update_temp_file();
|
void update_temp_file();
|
||||||
void help();
|
void help();
|
||||||
|
|
|
@ -4,11 +4,15 @@ namespace nasal {
|
||||||
|
|
||||||
bool symbol_finder::visit_definition_expr(definition_expr* node) {
|
bool symbol_finder::visit_definition_expr(definition_expr* node) {
|
||||||
if (node->get_variable_name()) {
|
if (node->get_variable_name()) {
|
||||||
|
// single variable definition
|
||||||
|
// example: var a = 1;
|
||||||
symbols.push_back({
|
symbols.push_back({
|
||||||
node->get_variable_name()->get_name(),
|
node->get_variable_name()->get_name(),
|
||||||
node->get_variable_name()->get_location()
|
node->get_variable_name()->get_location()
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
// multiple variable definition
|
||||||
|
// example: var (a, b, c) = (0, 1, 2);
|
||||||
for(auto i : node->get_variables()->get_variables()) {
|
for(auto i : node->get_variables()->get_variables()) {
|
||||||
symbols.push_back({
|
symbols.push_back({
|
||||||
i->get_name(),
|
i->get_name(),
|
||||||
|
@ -25,6 +29,7 @@ bool symbol_finder::visit_definition_expr(definition_expr* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool symbol_finder::visit_function(function* node) {
|
bool symbol_finder::visit_function(function* node) {
|
||||||
|
// do not scan variables defined in function inside this code block
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# and use this script to get property tree
|
# and use this script to get property tree
|
||||||
# 2023/11/06 ValKmjolnir
|
# 2023/11/06 ValKmjolnir
|
||||||
|
|
||||||
use module.libsock;
|
use module.libnasock;
|
||||||
use std.json;
|
use std.json;
|
||||||
use std.os;
|
use std.os;
|
||||||
use std.unix;
|
use std.unix;
|
||||||
|
@ -30,7 +30,7 @@ var _get_time = func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var _connect = func(hostname, port) {
|
var _connect = func(hostname, port) {
|
||||||
var socket = libsock.socket;
|
var socket = libnasock.socket;
|
||||||
var sd = socket.socket(
|
var sd = socket.socket(
|
||||||
socket.AF_INET,
|
socket.AF_INET,
|
||||||
socket.SOCK_STREAM,
|
socket.SOCK_STREAM,
|
||||||
|
@ -46,7 +46,7 @@ var _connect = func(hostname, port) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var new = func(hostname, port) {
|
var new = func(hostname, port) {
|
||||||
var socket = libsock.socket;
|
var socket = libnasock.socket;
|
||||||
var sd = _connect(hostname, port);
|
var sd = _connect(hostname, port);
|
||||||
|
|
||||||
var getprop = func(path) {
|
var getprop = func(path) {
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# regex.nas
|
||||||
|
# 2024/3/1 by ValKmjolnir
|
||||||
|
|
||||||
|
var match = func(src, reg) {
|
||||||
|
return __regex_match(src, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
var search = func(src, reg) {
|
||||||
|
return __regex_search(src, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
var replace = func(src, reg, fmt) {
|
||||||
|
return __regex_replace(src, reg, fmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
var match_all = func(src, reg) {
|
||||||
|
return __regex_match_all(src, reg);
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
use module.libsock;
|
use module.libnasock;
|
||||||
use std.os;
|
use std.os;
|
||||||
use std.unix;
|
use std.unix;
|
||||||
|
|
||||||
var udp_server = func(hostname, port, retry_delay = 5) {
|
var udp_server = func(hostname, port, retry_delay = 5) {
|
||||||
var socket = libsock.socket;
|
var socket = libnasock.socket;
|
||||||
var server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM);
|
var server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM);
|
||||||
while(socket.bind(server, hostname, port) < 0) {
|
while(socket.bind(server, hostname, port) < 0) {
|
||||||
println("[", os.time(), "] failed to bind socket "~server~" at ", hostname, ":", port, ".");
|
println("[", os.time(), "] failed to bind socket "~server~" at ", hostname, ":", port, ".");
|
||||||
|
@ -26,7 +26,7 @@ var udp_server = func(hostname, port, retry_delay = 5) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var udp_client = func(hostname = "", port = -1, retry_delay = 5) {
|
var udp_client = func(hostname = "", port = -1, retry_delay = 5) {
|
||||||
var socket = libsock.socket;
|
var socket = libnasock.socket;
|
||||||
var client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM);
|
var client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM);
|
||||||
if (port > 0 and size(hostname) != 0) {
|
if (port > 0 and size(hostname) != 0) {
|
||||||
while(socket.bind(client, hostname, port)<0) {
|
while(socket.bind(client, hostname, port)<0) {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use module.libsock;
|
use module.libnasock;
|
||||||
use std.os;
|
use std.os;
|
||||||
use std.io;
|
use std.io;
|
||||||
use std.unix;
|
use std.unix;
|
||||||
|
|
||||||
var socket = libsock.socket;
|
var socket = libnasock.socket;
|
||||||
|
|
||||||
var http = func() {
|
var http = func() {
|
||||||
var sd=nil;
|
var sd=nil;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use module.libsock;
|
use module.libnasock;
|
||||||
use std.json;
|
use std.json;
|
||||||
use std.runtime;
|
use std.runtime;
|
||||||
use std.os;
|
use std.os;
|
||||||
use std.unix;
|
use std.unix;
|
||||||
|
|
||||||
var socket = libsock.socket;
|
var socket = libnasock.socket;
|
||||||
|
|
||||||
var gettime = func() {
|
var gettime = func() {
|
||||||
return split(" ",os.time())[1];
|
return split(" ",os.time())[1];
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
use std.regex;
|
||||||
|
|
||||||
|
println(regex.match("aaa", "[a]*"));
|
||||||
|
println(regex.search("aabcaa", "abc"));
|
||||||
|
|
||||||
|
var s = "aaaaa";
|
||||||
|
println(regex.replace(s, "a", "[$&]"));
|
||||||
|
println(s);
|
||||||
|
|
||||||
|
println(regex.match_all("a,b,c,d,e,f,g,h,i", "[a-z]"));
|
|
@ -0,0 +1,66 @@
|
||||||
|
import tarfile
|
||||||
|
import pathlib
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
|
||||||
|
nasal_version = "11.1"
|
||||||
|
|
||||||
|
build_directory = pathlib.Path("build")
|
||||||
|
if not os.path.exists(build_directory):
|
||||||
|
print("pack binaries failed: build directory not found")
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
nasal_executable = pathlib.Path("nasal")
|
||||||
|
nasal_standard_library = pathlib.Path("std")
|
||||||
|
if not os.path.exists(nasal_executable):
|
||||||
|
print("pack binaries failed: nasal executable not found")
|
||||||
|
exit(-1)
|
||||||
|
if not os.path.exists(nasal_standard_library):
|
||||||
|
print("pack binaries failed: nasal standard library not found")
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
nasal_module_directory = pathlib.Path("module")
|
||||||
|
if not os.path.exists(nasal_module_directory):
|
||||||
|
print("pack binaries failed: nasal module directory not found")
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
dynamic_library_suffix = ""
|
||||||
|
if platform.system()=="Windows":
|
||||||
|
dynamic_library_suffix = ".dll"
|
||||||
|
else:
|
||||||
|
dynamic_library_suffix = ".so"
|
||||||
|
|
||||||
|
nasal_modules = []
|
||||||
|
for m in ["libfib", "libkey", "libmat", "libnasock"]:
|
||||||
|
path = pathlib.Path("module").joinpath(m + dynamic_library_suffix)
|
||||||
|
if not os.path.exists(path):
|
||||||
|
print("pack binaries failed: nasal module `{}` not found".format(m))
|
||||||
|
exit(-1)
|
||||||
|
lib = pathlib.Path("module").joinpath(m + ".nas")
|
||||||
|
if not os.path.exists(lib):
|
||||||
|
print("pack binaries failed: nasal module lib `{}.nas` not found".format(m))
|
||||||
|
exit(-1)
|
||||||
|
nasal_modules.append(path)
|
||||||
|
nasal_modules.append(lib)
|
||||||
|
|
||||||
|
|
||||||
|
tar_file_name = "nasal-{}".format(platform.system())
|
||||||
|
# create package directory in build directory and copy files needed
|
||||||
|
package_directory = build_directory.joinpath(tar_file_name)
|
||||||
|
if not os.path.exists(package_directory):
|
||||||
|
os.mkdir(package_directory)
|
||||||
|
os.mkdir(package_directory.joinpath("module"))
|
||||||
|
print("pack nasal executable")
|
||||||
|
shutil.copy(nasal_executable, package_directory.joinpath(nasal_executable))
|
||||||
|
print("pack nasal standard library")
|
||||||
|
shutil.copytree(nasal_standard_library, package_directory.joinpath(nasal_standard_library))
|
||||||
|
for m in nasal_modules:
|
||||||
|
print("pack nasal module:", m)
|
||||||
|
shutil.copy(m, package_directory.joinpath(m))
|
||||||
|
|
||||||
|
file = tarfile.open(name=tar_file_name + ".tar", mode="w")
|
||||||
|
file.add(package_directory)
|
||||||
|
print("pack succeeded")
|
||||||
|
file.close()
|
Loading…
Reference in New Issue