🚀 switch build script to new nasal

This commit is contained in:
ValKmjolnir 2023-07-02 00:32:13 +08:00
parent 597c0388cb
commit a7a2f47d1e
12 changed files with 348 additions and 340 deletions

View File

@ -16,9 +16,9 @@ jobs:
- uses: actions/checkout@v2
- name: make
run: |
make
make -j
cd module
make all
make all -j
cd ..
make test
tar -czf nasal-mac-nightly.tgz .
@ -42,9 +42,9 @@ jobs:
- uses: actions/checkout@v2
- name: make
run: |
make
make -j
cd module
make all
make all -j
cd ..
make test
touch nasal-linux-x86_64-nightly.tgz

View File

@ -4,7 +4,7 @@ project(nasal VERSION 10.1)
message("CMAKE_HOST_SYSTEM_NAME: ${CMAKE_HOST_SYSTEM_NAME}")
# -std=c++14 -Wshadow -Wall
# -std=c++17 -Wshadow -Wall
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_FLAGS_RELEASE_INIT "-Wshadow -Wall")
@ -14,24 +14,45 @@ set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/module)
add_library(fib SHARED ${CMAKE_SOURCE_DIR}/module/fib.cpp)
target_include_directories(fib PRIVATE ${CMAKE_SOURCE_DIR})
target_include_directories(fib PRIVATE ${CMAKE_SOURCE_DIR}/src)
add_library(key SHARED ${CMAKE_SOURCE_DIR}/module/keyboard.cpp)
target_include_directories(key PRIVATE ${CMAKE_SOURCE_DIR})
target_include_directories(key PRIVATE ${CMAKE_SOURCE_DIR}/src)
add_library(mat SHARED ${CMAKE_SOURCE_DIR}/module/matrix.cpp)
target_include_directories(mat PRIVATE ${CMAKE_SOURCE_DIR})
target_include_directories(mat PRIVATE ${CMAKE_SOURCE_DIR}/src)
add_library(nasock SHARED ${CMAKE_SOURCE_DIR}/module/nasocket.cpp)
target_include_directories(nasock PRIVATE ${CMAKE_SOURCE_DIR})
target_include_directories(nasock PRIVATE ${CMAKE_SOURCE_DIR}/src)
add_executable(nasal main.cpp)
set(NASAL_OBJECT_SOURCE_FILE
${CMAKE_SOURCE_DIR}/src/ast_dumper.cpp
${CMAKE_SOURCE_DIR}/src/ast_visitor.cpp
${CMAKE_SOURCE_DIR}/src/nasal_new_ast.cpp
${CMAKE_SOURCE_DIR}/src/nasal_new_builtin.cpp
${CMAKE_SOURCE_DIR}/src/nasal_new_codegen.cpp
${CMAKE_SOURCE_DIR}/src/nasal_new_dbg.cpp
${CMAKE_SOURCE_DIR}/src/nasal_new_err.cpp
${CMAKE_SOURCE_DIR}/src/nasal_new_gc.cpp
${CMAKE_SOURCE_DIR}/src/nasal_new_import.cpp
${CMAKE_SOURCE_DIR}/src/nasal_new_lexer.cpp
${CMAKE_SOURCE_DIR}/src/nasal_new_misc.cpp
${CMAKE_SOURCE_DIR}/src/nasal_new_opcode.cpp
${CMAKE_SOURCE_DIR}/src/nasal_new_parse.cpp
${CMAKE_SOURCE_DIR}/src/nasal_new_vm.cpp
${CMAKE_SOURCE_DIR}/src/optimizer.cpp
${CMAKE_SOURCE_DIR}/src/symbol_finder.cpp)
add_executable(nasal ${CMAKE_SOURCE_DIR}/src/nasal_new_main.cpp)
add_library(nasal-object STATIC ${NASAL_OBJECT_SOURCE_FILE})
target_include_directories(nasal-object PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_link_libraries(nasal nasal-object)
if(NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
target_link_libraries(nasal dl)
endif()
target_include_directories(nasal PRIVATE ${CMAKE_SOURCE_DIR})
target_include_directories(nasal PRIVATE ${CMAKE_SOURCE_DIR}/src)
if(NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
add_custom_command(

View File

@ -4,7 +4,7 @@
![GitHub code size](https://img.shields.io/github/languages/code-size/ValKmjolnir/Nasal-Interpreter?style=flat-square&logo=github)
![GitHub release(latest by date)](https://img.shields.io/github/v/release/ValKmjolnir/Nasal-Interpreter?style=flat-square&logo=github)
![in dev](https://img.shields.io/badge/dev-v10.1-blue?style=flat-square&logo=github)
![in dev](https://img.shields.io/badge/dev-v11.0-blue?style=flat-square&logo=github)
[![license](https://img.shields.io/badge/license-MIT-green?style=flat-square&logo=github)](./LICENSE)
> This document is also available in: [__中文__](./doc/README_zh.md) | [__English__](./README.md)

View File

@ -4,7 +4,7 @@
![GitHub code size](https://img.shields.io/github/languages/code-size/ValKmjolnir/Nasal-Interpreter?style=flat-square&logo=github)
![GitHub release(latest by date)](https://img.shields.io/github/v/release/ValKmjolnir/Nasal-Interpreter?style=flat-square&logo=github)
![in dev](https://img.shields.io/badge/dev-v10.1-blue?style=flat-square&logo=github)
![in dev](https://img.shields.io/badge/dev-v11.0-blue?style=flat-square&logo=github)
[![license](https://img.shields.io/badge/license-MIT-green?style=flat-square&logo=github)](../LICENSE)
> 这篇文档包含多语言版本: [__中文__](../doc/README_zh.md) | [__English__](../README.md)

154
makefile
View File

@ -1,79 +1,8 @@
.PHONY:test clean
SRC=\
main.cpp\
nasal_ast.h\
nasal_err.h\
nasal_builtin.h\
nasal_opcode.h\
nasal_opt.h\
nasal_codegen.h\
nasal_gc.h\
nasal_import.h\
nasal_lexer.h\
nasal_parse.h\
nasal_vm.h\
nasal_dbg.h\
nasal.h
STD=c++17
nasal:$(SRC)
$(CXX) -std=$(STD) -O3 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall
nasal.exe:$(SRC)
$(CXX) -std=$(STD) -O3 main.cpp -o nasal.exe -fno-exceptions -Wshadow -Wall -static
stable-release:$(SRC)
$(CXX) -std=$(STD) -O2 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall
stable-release-mingw:$(SRC)
$(CXX) -std=$(STD) -O2 main.cpp -o nasal.exe -fno-exceptions -Wshadow -Wall -static
clean:
@ echo "[clean] nasal" && if [ -e nasal ]; then rm nasal; fi
@ echo "[clean] nasal.exe" && if [ -e nasal.exe ]; then rm nasal.exe; fi
test:nasal
@ ./nasal -e test/ascii-art.nas
@ ./nasal -t -d test/bfs.nas
@ ./nasal -t test/bigloop.nas
@ ./nasal -t test/bp.nas
@ ./nasal -d test/calc.nas
@ ./nasal -e test/choice.nas
@ ./nasal -e test/class.nas
@ ./nasal -t -d test/console3D.nas 20
@ ./nasal -e test/coroutine.nas
@ ./nasal -t -d test/datalog.nas
@ ./nasal -e test/diff.nas
@ ./nasal -e test/donuts.nas 15
-@ ./nasal -d test/exception.nas
@ ./nasal -t -d test/fib.nas
@ ./nasal -e test/filesystem.nas
@ ./nasal -d test/hexdump.nas
@ ./nasal -e test/json.nas
@ ./nasal -e test/leetcode1319.nas
@ ./nasal -d test/lexer.nas
@ ./nasal -d test/life.nas
@ ./nasal -t test/loop.nas
@ ./nasal -t test/mandelbrot.nas
@ ./nasal -t test/md5.nas
@ ./nasal -t -d test/md5compare.nas
@ ./nasal -d test/module_test.nas
@ ./nasal -e test/nasal_test.nas
@ ./nasal -t -d test/occupation.nas 2
@ ./nasal -t -d test/pi.nas
@ ./nasal -t -d test/prime.nas
@ ./nasal -e test/qrcode.nas
@ ./nasal -t -d test/quick_sort.nas
@ ./nasal -e test/scalar.nas hello world
@ ./nasal -e test/trait.nas
@ ./nasal -t -d test/turingmachine.nas
@ ./nasal -d test/wavecollapse.nas
@ ./nasal test/word_collector.nas test/md5compare.nas
@ ./nasal -t -d test/ycombinator.nas
NASAL_NEW_AST=\
NASAL_OBJECT=\
nasal_new_err.o\
nasal_new_ast.o\
ast_visitor.o\
@ -93,11 +22,11 @@ NASAL_NEW_AST=\
nasal_new_main.o
# for test
nnew: $(NASAL_NEW_AST)
$(CXX) $(NASAL_NEW_AST) -O3 -o nnew -ldl
nasal: $(NASAL_OBJECT)
$(CXX) $(NASAL_OBJECT) -O3 -o nasal -ldl
nnew.exe: $(NASAL_NEW_AST)
$(CXX) $(NASAL_NEW_AST) -O3 -o nnew.exe
nasal.exe: $(NASAL_OBJECT)
$(CXX) $(NASAL_OBJECT) -O3 -o nasal.exe
nasal_new_main.o: src/nasal_new_main.cpp
$(CXX) -std=$(STD) -c -O3 src/nasal_new_main.cpp -fno-exceptions -fPIC -o nasal_new_main.o -I .
@ -152,4 +81,75 @@ nasal_new_dbg.o: src/nasal_new_dbg.h src/nasal_new_dbg.cpp
.PHONY: nasal_new_clean
nasal_new_clean:
rm $(NASAL_NEW_AST)
rm $(NASAL_OBJECT)
SRC=\
main.cpp\
nasal_ast.h\
nasal_err.h\
nasal_builtin.h\
nasal_opcode.h\
nasal_opt.h\
nasal_codegen.h\
nasal_gc.h\
nasal_import.h\
nasal_lexer.h\
nasal_parse.h\
nasal_vm.h\
nasal_dbg.h\
nasal.h
nasal_old:$(SRC)
$(CXX) -std=$(STD) -O3 main.cpp -o nasal_old -fno-exceptions -ldl -Wshadow -Wall
nasal_old.exe:$(SRC)
$(CXX) -std=$(STD) -O3 main.cpp -o nasal_old.exe -fno-exceptions -Wshadow -Wall -static
stable-release:$(SRC)
$(CXX) -std=$(STD) -O2 main.cpp -o nasal_old -fno-exceptions -ldl -Wshadow -Wall
stable-release-mingw:$(SRC)
$(CXX) -std=$(STD) -O2 main.cpp -o nasal_old.exe -fno-exceptions -Wshadow -Wall -static
clean:
@ echo "[clean] nasal" && if [ -e nasal ]; then rm nasal; fi
@ echo "[clean] nasal.exe" && if [ -e nasal.exe ]; then rm nasal.exe; fi
test:nasal
@ ./nasal -e test/ascii-art.nas
@ ./nasal -t -d test/bfs.nas
@ ./nasal -t test/bigloop.nas
@ ./nasal -t test/bp.nas
@ ./nasal -d test/calc.nas
@ ./nasal -e test/choice.nas
@ ./nasal -e test/class.nas
@ ./nasal -t -d test/console3D.nas 20
@ ./nasal -e test/coroutine.nas
@ ./nasal -t -d test/datalog.nas
@ ./nasal -e test/diff.nas
@ ./nasal -e test/donuts.nas 15
-@ ./nasal -d test/exception.nas
@ ./nasal -t -d test/fib.nas
@ ./nasal -e test/filesystem.nas
@ ./nasal -d test/hexdump.nas
@ ./nasal -e test/json.nas
@ ./nasal -e test/leetcode1319.nas
@ ./nasal -d test/lexer.nas
@ ./nasal -d test/life.nas
@ ./nasal -t test/loop.nas
@ ./nasal -t test/mandelbrot.nas
@ ./nasal -t test/md5.nas
@ ./nasal -t -d test/md5compare.nas
@ ./nasal -d test/module_test.nas
@ ./nasal -e test/nasal_test.nas
@ ./nasal -t -d test/occupation.nas 2
@ ./nasal -t -d test/pi.nas
@ ./nasal -t -d test/prime.nas
@ ./nasal -e test/qrcode.nas
@ ./nasal -t -d test/quick_sort.nas
@ ./nasal -e test/scalar.nas hello world
@ ./nasal -e test/trait.nas
@ ./nasal -t -d test/turingmachine.nas
@ ./nasal -d test/wavecollapse.nas
@ ./nasal test/word_collector.nas test/md5compare.nas
@ ./nasal -t -d test/ycombinator.nas

View File

@ -3,7 +3,7 @@
dynamic_libs_so=libfib.so libkey.so libnasock.so libmat.so
dynamic_libs_dll=libfib.dll libkey.dll libnasock.dll libmat.dll
used_header= ../nasal.h ../nasal_gc.h
used_header= ../src/nasal_new_header.h ../src/nasal_new_gc.h
STD=c++17

View File

@ -100,34 +100,34 @@ void codegen::gen(u8 operation_code, u32 num, u32 line) {
void codegen::num_gen(number_literal* node) {
f64 num = node->get_number();
regist_num(num);
gen(op_pnum,num_table.at(num), node->get_location().begin_line);
gen(op_pnum,num_table.at(num), node->get_line());
}
void codegen::str_gen(string_literal* node) {
regist_str(node->get_content());
gen(op_pstr, str_table.at(node->get_content()), node->get_location().begin_line);
gen(op_pstr, str_table.at(node->get_content()), node->get_line());
}
void codegen::bool_gen(bool_literal* node) {
f64 num = node->get_flag()? 1:0;
regist_num(num);
gen(op_pnum, num_table.at(num), node->get_location().begin_line);
gen(op_pnum, num_table.at(num), node->get_line());
}
void codegen::vec_gen(vector_expr* node) {
for(auto child : node->get_elements()) {
calc_gen(child);
}
gen(op_newv, node->get_elements().size(), node->get_location().begin_line);
gen(op_newv, node->get_elements().size(), node->get_line());
}
void codegen::hash_gen(hash_expr* node) {
gen(op_newh, 0, node->get_location().begin_line);
gen(op_newh, 0, node->get_line());
for(auto child : node->get_members()) {
calc_gen(child->get_value());
const auto& field_name = child->get_name();
regist_str(field_name);
gen(op_happ, str_table.at(field_name), child->get_location().begin_line);
gen(op_happ, str_table.at(field_name), child->get_line());
}
}
@ -167,9 +167,9 @@ void codegen::func_gen(function* node) {
}
usize newf=code.size();
gen(op_newf, 0, node->get_location().begin_line);
gen(op_newf, 0, node->get_line());
usize lsize=code.size();
gen(op_intl, 0, node->get_location().begin_line);
gen(op_intl, 0, node->get_line());
// add special keyword 'me' into symbol table
// this symbol is only used in local scope(function's scope)
@ -188,14 +188,14 @@ void codegen::func_gen(function* node) {
regist_str(name);
switch(tmp->get_parameter_type()) {
case parameter::param_type::normal_parameter:
gen(op_para, str_table.at(name), tmp->get_location().begin_line);
gen(op_para, str_table.at(name), tmp->get_line());
break;
case parameter::param_type::default_parameter:
calc_gen(tmp->get_default_value());
gen(op_deft, str_table.at(name), tmp->get_location().begin_line);
gen(op_deft, str_table.at(name), tmp->get_line());
break;
case parameter::param_type::dynamic_parameter:
gen(op_dyn, str_table.at(name), tmp->get_location().begin_line);
gen(op_dyn, str_table.at(name), tmp->get_line());
break;
}
add_sym(name);
@ -203,7 +203,7 @@ void codegen::func_gen(function* node) {
code[newf].num = code.size()+1; // entry
usize jmp_ptr = code.size();
gen(op_jmp, 0, node->get_location().begin_line);
gen(op_jmp, 0, node->get_line());
auto block = node->get_code_block();
// search symbols first, must use after loading parameters
@ -221,8 +221,8 @@ void codegen::func_gen(function* node) {
if (!block->get_expressions().size() ||
block->get_expressions().back()->get_type()!=expr_type::ast_ret) {
gen(op_pnil, 0, block->get_location().begin_line);
gen(op_ret, 0, block->get_location().begin_line);
gen(op_pnil, 0, block->get_line());
gen(op_ret, 0, block->get_line());
}
code[jmp_ptr].num = code.size();
}
@ -245,7 +245,7 @@ void codegen::call_id(identifier* node) {
const auto& name = node->get_name();
for(u32 i = 0; builtin[i].name; ++i) {
if (builtin[i].name==name) {
gen(op_callb, i, node->get_location().begin_line);
gen(op_callb, i, node->get_line());
if (local.empty()) {
die("should warp native function in local scope",
node->get_location());
@ -255,15 +255,15 @@ void codegen::call_id(identifier* node) {
}
i32 index;
if ((index=local_find(name))>=0) {
gen(op_calll, index, node->get_location().begin_line);
gen(op_calll, index, node->get_line());
return;
}
if ((index=upvalue_find(name))>=0) {
gen(op_upval, index, node->get_location().begin_line);
gen(op_upval, index, node->get_line());
return;
}
if ((index=global_find(name))>=0) {
gen(op_callg, index, node->get_location().begin_line);
gen(op_callg, index, node->get_line());
return;
}
die("undefined symbol \"" + name + "\"", node->get_location());
@ -271,7 +271,7 @@ void codegen::call_id(identifier* node) {
void codegen::call_hash_gen(call_hash* node) {
regist_str(node->get_field());
gen(op_callh, str_table.at(node->get_field()), node->get_location().begin_line);
gen(op_callh, str_table.at(node->get_field()), node->get_line());
}
void codegen::call_vec(call_vector* node) {
@ -279,39 +279,39 @@ void codegen::call_vec(call_vector* node) {
if (node->get_slices().size()==1 &&
!node->get_slices()[0]->get_end()) {
calc_gen(node->get_slices()[0]->get_begin());
gen(op_callv, 0, node->get_slices()[0]->get_location().begin_line);
gen(op_callv, 0, node->get_slices()[0]->get_line());
return;
}
gen(op_slcbeg, 0, node->get_location().begin_line);
gen(op_slcbeg, 0, node->get_line());
for(auto tmp : node->get_slices()) {
if (!tmp->get_end()) {
calc_gen(tmp->get_begin());
gen(op_slc, 0, tmp->get_location().begin_line);
gen(op_slc, 0, tmp->get_line());
} else {
calc_gen(tmp->get_begin());
calc_gen(tmp->get_end());
gen(op_slc2, 0, tmp->get_location().begin_line);
gen(op_slc2, 0, tmp->get_line());
}
}
gen(op_slcend, 0, node->get_location().begin_line);
gen(op_slcend, 0, node->get_line());
}
void codegen::call_func(call_function* node) {
if (node->get_argument().size() &&
node->get_argument()[0]->get_type()==expr_type::ast_pair) {
gen(op_newh, 0, node->get_location().begin_line);
gen(op_newh, 0, node->get_line());
for(auto child : node->get_argument()) {
calc_gen(((hash_pair*)child)->get_value());
const auto& field_name = ((hash_pair*)child)->get_name();
regist_str(field_name);
gen(op_happ, str_table.at(field_name), child->get_location().begin_line);
gen(op_happ, str_table.at(field_name), child->get_line());
}
gen(op_callfh, 0, node->get_location().begin_line);
gen(op_callfh, 0, node->get_line());
} else {
for(auto child : node->get_argument()) {
calc_gen(child);
}
gen(op_callfv, node->get_argument().size(), node->get_location().begin_line);
gen(op_callfv, node->get_argument().size(), node->get_line());
}
}
@ -365,15 +365,15 @@ void codegen::mcall_id(identifier* node) {
}
i32 index;
if ((index=local_find(name))>=0) {
gen(op_mcalll, index, node->get_location().begin_line);
gen(op_mcalll, index, node->get_line());
return;
}
if ((index=upvalue_find(name))>=0) {
gen(op_mupval, index, node->get_location().begin_line);
gen(op_mupval, index, node->get_line());
return;
}
if ((index=global_find(name))>=0) {
gen(op_mcallg, index, node->get_location().begin_line);
gen(op_mcallg, index, node->get_line());
return;
}
die("undefined symbol \"" + name + "\"", node->get_location());
@ -390,20 +390,20 @@ void codegen::mcall_vec(call_vector* node) {
return;
}
calc_gen(call->get_begin());
gen(op_mcallv, 0, node->get_location().begin_line);
gen(op_mcallv, 0, node->get_line());
}
void codegen::mcall_hash(call_hash* node) {
regist_str(node->get_field());
gen(op_mcallh, str_table.at(node->get_field()), node->get_location().begin_line);
gen(op_mcallh, str_table.at(node->get_field()), node->get_line());
}
void codegen::single_def(definition_expr* node) {
const auto& str = node->get_variable_name()->get_name();
calc_gen(node->get_value());
local.empty()?
gen(op_loadg, global_find(str), node->get_location().begin_line):
gen(op_loadl, local_find(str), node->get_location().begin_line);
gen(op_loadg, global_find(str), node->get_line()):
gen(op_loadl, local_find(str), node->get_line());
}
void codegen::multi_def(definition_expr* node) {
@ -420,19 +420,19 @@ void codegen::multi_def(definition_expr* node) {
calc_gen(vals[i]);
const auto& name = identifiers[i]->get_name();
local.empty()?
gen(op_loadg, global_find(name), identifiers[i]->get_location().begin_line):
gen(op_loadl, local_find(name), identifiers[i]->get_location().begin_line);
gen(op_loadg, global_find(name), identifiers[i]->get_line()):
gen(op_loadl, local_find(name), identifiers[i]->get_line());
}
} else { // (var a,b,c)=[0,1,2];
calc_gen(node->get_value());
for(usize i = 0; i<size; ++i) {
gen(op_callvi, i, node->get_value()->get_location().begin_line);
gen(op_callvi, i, node->get_value()->get_line());
const auto& name = identifiers[i]->get_name();
local.empty()?
gen(op_loadg, global_find(name), identifiers[i]->get_location().begin_line):
gen(op_loadl, local_find(name), identifiers[i]->get_location().begin_line);
gen(op_loadg, global_find(name), identifiers[i]->get_line()):
gen(op_loadl, local_find(name), identifiers[i]->get_line());
}
gen(op_pop, 0, node->get_location().begin_line);
gen(op_pop, 0, node->get_line());
}
}
@ -449,7 +449,7 @@ void codegen::assignment_gen(assignment_expr* node) {
case assignment_expr::assign_type::equal:
calc_gen(node->get_right());
mcall(node->get_left());
gen(op_meq, 0, node->get_location().begin_line);
gen(op_meq, 0, node->get_line());
break;
case assignment_expr::assign_type::add_equal:
if (node->get_right()->get_type()!=expr_type::ast_num) {
@ -457,11 +457,11 @@ void codegen::assignment_gen(assignment_expr* node) {
}
mcall(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
gen(op_addeq, 0, node->get_location().begin_line);
gen(op_addeq, 0, node->get_line());
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_addeqc, num_table[num], node->get_location().begin_line);
gen(op_addeqc, num_table[num], node->get_line());
}
break;
case assignment_expr::assign_type::sub_equal:
@ -470,11 +470,11 @@ void codegen::assignment_gen(assignment_expr* node) {
}
mcall(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
gen(op_subeq, 0, node->get_location().begin_line);
gen(op_subeq, 0, node->get_line());
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_subeqc, num_table[num], node->get_location().begin_line);
gen(op_subeqc, num_table[num], node->get_line());
}
break;
case assignment_expr::assign_type::mult_equal:
@ -483,11 +483,11 @@ void codegen::assignment_gen(assignment_expr* node) {
}
mcall(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
gen(op_muleq, 0, node->get_location().begin_line);
gen(op_muleq, 0, node->get_line());
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_muleqc, num_table[num], node->get_location().begin_line);
gen(op_muleqc, num_table[num], node->get_line());
}
break;
case assignment_expr::assign_type::div_equal:
@ -496,11 +496,11 @@ void codegen::assignment_gen(assignment_expr* node) {
}
mcall(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
gen(op_diveq, 0, node->get_location().begin_line);
gen(op_diveq, 0, node->get_line());
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_diveqc, num_table[num], node->get_location().begin_line);
gen(op_diveqc, num_table[num], node->get_line());
}
break;
case assignment_expr::assign_type::concat_equal:
@ -509,27 +509,27 @@ void codegen::assignment_gen(assignment_expr* node) {
}
mcall(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_str) {
gen(op_lnkeq, 0, node->get_location().begin_line);
gen(op_lnkeq, 0, node->get_line());
} else {
const auto& str = ((string_literal*)node->get_right())->get_content();
regist_str(str);
gen(op_lnkeqc, str_table[str], node->get_location().begin_line);
gen(op_lnkeqc, str_table[str], node->get_line());
}
break;
case assignment_expr::assign_type::bitwise_and_equal:
calc_gen(node->get_right());
mcall(node->get_left());
gen(op_btandeq, 0, node->get_location().begin_line);
gen(op_btandeq, 0, node->get_line());
break;
case assignment_expr::assign_type::bitwise_or_equal:
calc_gen(node->get_right());
mcall(node->get_left());
gen(op_btoreq, 0, node->get_location().begin_line);
gen(op_btoreq, 0, node->get_line());
break;
case assignment_expr::assign_type::bitwise_xor_equal:
calc_gen(node->get_right());
mcall(node->get_left());
gen(op_btxoreq, 0, node->get_location().begin_line);
gen(op_btxoreq, 0, node->get_line());
break;
}
}
@ -553,7 +553,7 @@ void codegen::assign_statement(assignment_expr* node) {
if (code.back().op==op_meq) {
code.back().num=1;
} else {
gen(op_pop, 0, node->get_location().begin_line);
gen(op_pop, 0, node->get_line());
}
}
break;
@ -571,7 +571,7 @@ void codegen::assign_statement(assignment_expr* node) {
} else if (op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) {
code.back().op=code.back().op-op_addeqc+op_addecp;
} else {
gen(op_pop, 0, node->get_location().begin_line);
gen(op_pop, 0, node->get_line());
}
break;
}
@ -602,14 +602,14 @@ void codegen::multi_assign_gen(multi_assign* node) {
} else if (code.back().op==op_mcallg) {
code.back().op=op_loadg;
} else {
gen(op_meq, 1, tuple[i]->get_location().begin_line);
gen(op_meq, 1, tuple[i]->get_line());
}
}
} else {
calc_gen(node->get_value());
auto& tuple = node->get_tuple()->get_elements();
for(i32 i = 0; i<size; ++i) {
gen(op_callvi, i, node->get_value()->get_location().begin_line);
gen(op_callvi, i, node->get_value()->get_line());
// multi assign user loadl and loadg to avoid meq's stack--
// and this operation changes local and global value directly
mcall(tuple[i]);
@ -620,10 +620,10 @@ void codegen::multi_assign_gen(multi_assign* node) {
} else if (code.back().op==op_mcallg) {
code.back().op=op_loadg;
} else {
gen(op_meq, 1, tuple[i]->get_location().begin_line);
gen(op_meq, 1, tuple[i]->get_line());
}
}
gen(op_pop, 0, node->get_location().begin_line);
gen(op_pop, 0, node->get_line());
}
}
@ -631,25 +631,25 @@ void codegen::cond_gen(condition_expr* node) {
std::vector<usize> jmp_label;
calc_gen(node->get_if_statement()->get_condition());
auto ptr = code.size();
gen(op_jf, 0, node->get_if_statement()->get_location().begin_line);
gen(op_jf, 0, node->get_if_statement()->get_line());
block_gen(node->get_if_statement()->get_code_block());
if (node->get_elsif_stataments().size() ||
node->get_else_statement()) {
jmp_label.push_back(code.size());
gen(op_jmp, 0, node->get_if_statement()->get_location().begin_line);
gen(op_jmp, 0, node->get_if_statement()->get_line());
}
code[ptr].num = code.size();
for(auto tmp : node->get_elsif_stataments()) {
calc_gen(tmp->get_condition());
ptr = code.size();
gen(op_jf, 0, tmp->get_location().begin_line);
gen(op_jf, 0, tmp->get_line());
block_gen(tmp->get_code_block());
// the last condition doesn't need to jmp
if (tmp!=node->get_elsif_stataments().back() ||
node->get_else_statement()) {
jmp_label.push_back(code.size());
gen(op_jmp, 0, tmp->get_location().begin_line);
gen(op_jmp, 0, tmp->get_line());
}
code[ptr].num=code.size();
}
@ -671,13 +671,7 @@ void codegen::loop_gen(expr* node) {
case expr_type::ast_for:
for_gen((for_expr*)node); break;
case expr_type::ast_forei:
if (((forei_expr*)node)->get_loop_type()==
forei_expr::forei_loop_type::forindex) {
forindex_gen((forei_expr*)node);
} else {
foreach_gen((forei_expr*)node);
}
break;
forei_gen((forei_expr*)node); break;
}
}
@ -696,10 +690,10 @@ void codegen::while_gen(while_expr* node) {
usize loop_ptr = code.size();
calc_gen(node->get_condition());
usize condition_ptr = code.size();
gen(op_jf, 0, node->get_condition()->get_location().begin_line);
gen(op_jf, 0, node->get_condition()->get_line());
block_gen(node->get_code_block());
gen(op_jmp, loop_ptr, node->get_code_block()->get_location().begin_line);
gen(op_jmp, loop_ptr, node->get_code_block()->get_line());
code[condition_ptr].num = code.size();
load_continue_break(code.size()-1, code.size());
}
@ -709,22 +703,58 @@ void codegen::for_gen(for_expr* node) {
usize jmp_place = code.size();
if (node->get_condition()->get_type()==expr_type::ast_null) {
regist_num(1);
gen(op_pnum, num_table.at(1), node->get_condition()->get_location().begin_line);
gen(op_pnum, num_table.at(1), node->get_condition()->get_line());
} else {
calc_gen(node->get_condition());
}
usize label_exit = code.size();
gen(op_jf, 0, node->get_condition()->get_location().begin_line);
gen(op_jf, 0, node->get_condition()->get_line());
block_gen(node->get_code_block());
usize continue_place = code.size();
expr_gen(node->get_step());
gen(op_jmp, jmp_place, node->get_step()->get_location().begin_line);
gen(op_jmp, jmp_place, node->get_step()->get_line());
code[label_exit].num = code.size();
load_continue_break(continue_place, code.size());
}
void codegen::forei_gen(forei_expr* node) {
calc_gen(node->get_value());
gen(op_cnt, 0, node->get_value()->get_line());
usize ptr = code.size();
if (node->get_loop_type()==forei_expr::forei_loop_type::forindex) {
gen(op_findex, 0, node->get_line());
} else {
gen(op_feach, 0, node->get_line());
}
if (node->get_iterator()->get_name()) { // define a new iterator
const auto& str = node->get_iterator()->get_name()->get_name();
local.empty()?
gen(op_loadg, global_find(str), node->get_iterator()->get_name()->get_line()):
gen(op_loadl, local_find(str), node->get_iterator()->get_name()->get_line());
} else { // use exist variable as the iterator
mcall(node->get_iterator()->get_call());
if (code.back().op==op_mcallg) {
code.back().op=op_loadg;
} else if (code.back().op==op_mcalll) {
code.back().op=op_loadl;
} else if (code.back().op==op_mupval) {
code.back().op=op_loadu;
} else {
gen(op_meq, 1, node->get_iterator()->get_line());
}
}
++in_iterloop.top();
block_gen(node->get_code_block());
--in_iterloop.top();
gen(op_jmp, ptr, node->get_line());
code[ptr].num=code.size();
load_continue_break(code.size()-1, code.size());
gen(op_pop, 0, node->get_value()->get_line());// pop vector
gen(op_pop, 0, node->get_line());// pop iterator
}
void codegen::expr_gen(expr* node) {
switch(node->get_type()) {
case expr_type::ast_null:break;
@ -735,112 +765,48 @@ void codegen::expr_gen(expr* node) {
case expr_type::ast_assign:
assign_statement((assignment_expr*)node); break;
case expr_type::ast_nil:case expr_type::ast_num:
case expr_type::ast_str:case expr_type::ast_bool:break;
case expr_type::ast_str:case expr_type::ast_bool: break;
case expr_type::ast_vec:case expr_type::ast_hash:
case expr_type::ast_func:case expr_type::ast_call:
case expr_type::ast_unary:
case expr_type::ast_binary:
case expr_type::ast_ternary:
calc_gen(node);
gen(op_pop, 0, node->get_location().begin_line);
gen(op_pop, 0, node->get_line());
break;
}
}
void codegen::forindex_gen(forei_expr* node) {
calc_gen(node->get_value());
gen(op_cnt, 0, node->get_value()->get_location().begin_line);
usize ptr = code.size();
gen(op_findex, 0, node->get_location().begin_line);
if (node->get_iterator()->get_name()) { // define a new iterator
const auto& str = node->get_iterator()->get_name()->get_name();
local.empty()?
gen(op_loadg, global_find(str), node->get_iterator()->get_name()->get_location().begin_line):
gen(op_loadl, local_find(str), node->get_iterator()->get_name()->get_location().begin_line);
} else { // use exist variable as the iterator
mcall(node->get_iterator()->get_call());
if (code.back().op==op_mcallg) {
code.back().op=op_loadg;
} else if (code.back().op==op_mcalll) {
code.back().op=op_loadl;
} else if (code.back().op==op_mupval) {
code.back().op=op_loadu;
} else {
gen(op_meq, 1, node->get_iterator()->get_location().begin_line);
}
}
++in_iterloop.top();
block_gen(node->get_code_block());
--in_iterloop.top();
gen(op_jmp, ptr, node->get_location().begin_line);
code[ptr].num=code.size();
load_continue_break(code.size()-1, code.size());
gen(op_pop, 0, node->get_value()->get_location().begin_line);// pop vector
gen(op_pop, 0, node->get_location().begin_line);// pop iterator
}
void codegen::foreach_gen(forei_expr* node) {
calc_gen(node->get_value());
gen(op_cnt, 0, node->get_location().begin_line);
usize ptr = code.size();
gen(op_feach, 0, node->get_location().begin_line);
if (node->get_iterator()->get_name()) { // define a new iterator
const auto& str = node->get_iterator()->get_name()->get_name();
local.empty()?
gen(op_loadg, global_find(str), node->get_iterator()->get_name()->get_location().begin_line):
gen(op_loadl, local_find(str), node->get_iterator()->get_name()->get_location().begin_line);
} else { // use exist variable as the iterator
mcall(node->get_iterator()->get_call());
if (code.back().op==op_mcallg) {
code.back().op=op_loadg;
} else if (code.back().op==op_mcalll) {
code.back().op=op_loadl;
} else if (code.back().op==op_mupval) {
code.back().op=op_loadu;
} else {
gen(op_meq, 1, node->get_iterator()->get_location().begin_line);
}
}
++in_iterloop.top();
block_gen(node->get_code_block());
--in_iterloop.top();
gen(op_jmp, ptr, node->get_location().begin_line);
code[ptr].num=code.size();
load_continue_break(code.size()-1, code.size());
gen(op_pop, 0, node->get_value()->get_location().begin_line); // pop vector
gen(op_pop, 0, node->get_location().begin_line); // pop iterator
}
void codegen::or_gen(binary_operator* node) {
calc_gen(node->get_left());
usize l1 = code.size();
gen(op_jt, 0, node->get_left()->get_location().begin_line);
gen(op_jt, 0, node->get_left()->get_line());
gen(op_pop, 0, node->get_left()->get_location().begin_line);
gen(op_pop, 0, node->get_left()->get_line());
calc_gen(node->get_right());
usize l2=code.size();
gen(op_jt, 0, node->get_right()->get_location().begin_line);
gen(op_jt, 0, node->get_right()->get_line());
gen(op_pop, 0, node->get_right()->get_location().begin_line);
gen(op_pnil, 0, node->get_right()->get_location().begin_line);
gen(op_pop, 0, node->get_right()->get_line());
gen(op_pnil, 0, node->get_right()->get_line());
code[l1].num = code[l2].num = code.size();
}
void codegen::and_gen(binary_operator* node) {
calc_gen(node->get_left());
gen(op_jt, code.size()+2, node->get_left()->get_location().begin_line);
gen(op_jt, code.size()+2, node->get_left()->get_line());
usize lfalse = code.size();
gen(op_jmp, 0, node->get_left()->get_location().begin_line);
gen(op_pop, 0, node->get_right()->get_location().begin_line);// jt jumps here
gen(op_jmp, 0, node->get_left()->get_line());
gen(op_pop, 0, node->get_right()->get_line());// jt jumps here
calc_gen(node->get_right());
gen(op_jt, code.size()+3, node->get_right()->get_location().begin_line);
gen(op_jt, code.size()+3, node->get_right()->get_line());
code[lfalse].num = code.size();
gen(op_pop, 0, node->get_right()->get_location().begin_line);
gen(op_pnil, 0, node->get_right()->get_location().begin_line);
gen(op_pop, 0, node->get_right()->get_line());
gen(op_pnil, 0, node->get_right()->get_line());
// jt jumps here
}
@ -848,11 +814,11 @@ void codegen::unary_gen(unary_operator* node) {
calc_gen(node->get_value());
switch(node->get_operator_type()) {
case unary_operator::unary_type::negative:
gen(op_usub, 0, node->get_location().begin_line); break;
gen(op_usub, 0, node->get_line()); break;
case unary_operator::unary_type::logical_not:
gen(op_lnot, 0, node->get_location().begin_line); break;
gen(op_lnot, 0, node->get_line()); break;
case unary_operator::unary_type::bitwise_not:
gen(op_bnot, 0, node->get_location().begin_line); break;
gen(op_bnot, 0, node->get_line()); break;
}
}
@ -866,27 +832,27 @@ void codegen::binary_gen(binary_operator* node) {
case binary_operator::binary_type::cmpeq:
calc_gen(node->get_left());
calc_gen(node->get_right());
gen(op_eq, 0, node->get_location().begin_line);
gen(op_eq, 0, node->get_line());
return;
case binary_operator::binary_type::cmpneq:
calc_gen(node->get_left());
calc_gen(node->get_right());
gen(op_neq, 0, node->get_location().begin_line);
gen(op_neq, 0, node->get_line());
return;
case binary_operator::binary_type::bitwise_or:
calc_gen(node->get_left());
calc_gen(node->get_right());
gen(op_btor, 0, node->get_location().begin_line);
gen(op_btor, 0, node->get_line());
return;
case binary_operator::binary_type::bitwise_xor:
calc_gen(node->get_left());
calc_gen(node->get_right());
gen(op_btxor, 0, node->get_location().begin_line);
gen(op_btxor, 0, node->get_line());
return;
case binary_operator::binary_type::bitwise_and:
calc_gen(node->get_left());
calc_gen(node->get_right());
gen(op_btand, 0, node->get_location().begin_line);
gen(op_btand, 0, node->get_line());
return;
default: break;
}
@ -895,99 +861,99 @@ void codegen::binary_gen(binary_operator* node) {
calc_gen(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
calc_gen(node->get_right());
gen(op_add, 0, node->get_location().begin_line);
gen(op_add, 0, node->get_line());
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_addc, num_table.at(num), node->get_location().begin_line);
gen(op_addc, num_table.at(num), node->get_line());
}
return;
case binary_operator::binary_type::sub:
calc_gen(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
calc_gen(node->get_right());
gen(op_sub, 0, node->get_location().begin_line);
gen(op_sub, 0, node->get_line());
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_subc, num_table.at(num), node->get_location().begin_line);
gen(op_subc, num_table.at(num), node->get_line());
}
return;
case binary_operator::binary_type::mult:
calc_gen(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
calc_gen(node->get_right());
gen(op_mul, 0, node->get_location().begin_line);
gen(op_mul, 0, node->get_line());
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_mulc, num_table.at(num), node->get_location().begin_line);
gen(op_mulc, num_table.at(num), node->get_line());
}
return;
case binary_operator::binary_type::div:
calc_gen(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
calc_gen(node->get_right());
gen(op_div, 0, node->get_location().begin_line);
gen(op_div, 0, node->get_line());
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_divc, num_table.at(num), node->get_location().begin_line);
gen(op_divc, num_table.at(num), node->get_line());
}
return;
case binary_operator::binary_type::concat:
calc_gen(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_str) {
calc_gen(node->get_right());
gen(op_lnk, 0, node->get_location().begin_line);
gen(op_lnk, 0, node->get_line());
} else {
const auto& str = ((string_literal*)node->get_right())->get_content();
regist_str(str);
gen(op_lnkc, str_table.at(str), node->get_location().begin_line);
gen(op_lnkc, str_table.at(str), node->get_line());
}
break;
case binary_operator::binary_type::less:
calc_gen(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
calc_gen(node->get_right());
gen(op_less, 0, node->get_location().begin_line);
gen(op_less, 0, node->get_line());
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_lessc, num_table.at(num), node->get_location().begin_line);
gen(op_lessc, num_table.at(num), node->get_line());
}
return;
case binary_operator::binary_type::leq:
calc_gen(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
calc_gen(node->get_right());
gen(op_leq, 0, node->get_location().begin_line);
gen(op_leq, 0, node->get_line());
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_leqc, num_table.at(num), node->get_location().begin_line);
gen(op_leqc, num_table.at(num), node->get_line());
}
return;
case binary_operator::binary_type::grt:
calc_gen(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
calc_gen(node->get_right());
gen(op_grt, 0, node->get_location().begin_line);
gen(op_grt, 0, node->get_line());
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_grtc, num_table.at(num), node->get_location().begin_line);
gen(op_grtc, num_table.at(num), node->get_line());
}
return;
case binary_operator::binary_type::geq:
calc_gen(node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
calc_gen(node->get_right());
gen(op_geq, 0, node->get_location().begin_line);
gen(op_geq, 0, node->get_line());
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_geqc, num_table.at(num), node->get_location().begin_line);
gen(op_geqc, num_table.at(num), node->get_line());
}
return;
}
@ -996,10 +962,10 @@ void codegen::binary_gen(binary_operator* node) {
void codegen::trino_gen(ternary_operator* node) {
calc_gen(node->get_condition());
usize lfalse = code.size();
gen(op_jf, 0, node->get_condition()->get_location().begin_line);
gen(op_jf, 0, node->get_condition()->get_line());
calc_gen(node->get_left());
usize lexit = code.size();
gen(op_jmp, 0, node->get_left()->get_location().begin_line);
gen(op_jmp, 0, node->get_left()->get_line());
code[lfalse].num = code.size();
calc_gen(node->get_right());
code[lexit].num = code.size();
@ -1008,7 +974,7 @@ void codegen::trino_gen(ternary_operator* node) {
void codegen::calc_gen(expr* node) {
switch(node->get_type()) {
case expr_type::ast_nil:
gen(op_pnil, 0, node->get_location().begin_line); break;
gen(op_pnil, 0, node->get_line()); break;
case expr_type::ast_num:
num_gen((number_literal*)node); break;
case expr_type::ast_str:
@ -1050,16 +1016,17 @@ void codegen::block_gen(code_block* node) {
case expr_type::ast_nil:case expr_type::ast_num:
case expr_type::ast_str:case expr_type::ast_bool:break;
case expr_type::ast_file_info:
fileindex = ((file_info*)tmp)->get_index(); break; // special node type in main block
// special node type in main block
fileindex = ((file_info*)tmp)->get_index(); break;
case expr_type::ast_cond:
cond_gen((condition_expr*)tmp); break;
case expr_type::ast_continue:
continue_ptr.front().push_back(code.size());
gen(op_jmp, 0, tmp->get_location().begin_line);
gen(op_jmp, 0, tmp->get_line());
break;
case expr_type::ast_break:
break_ptr.front().push_back(code.size());
gen(op_jmp, 0, tmp->get_location().begin_line);
gen(op_jmp, 0, tmp->get_line());
break;
case expr_type::ast_while:
case expr_type::ast_for:
@ -1082,11 +1049,11 @@ void codegen::block_gen(code_block* node) {
void codegen::ret_gen(return_expr* node) {
for(u32 i = 0; i<in_iterloop.top(); ++i) {
gen(op_pop, 0, node->get_location().begin_line);
gen(op_pop, 0, node->get_location().begin_line);
gen(op_pop, 0, node->get_line());
gen(op_pop, 0, node->get_line());
}
calc_gen(node->get_value());
gen(op_ret, 0, node->get_location().begin_line);
gen(op_ret, 0, node->get_line());
}
const error& codegen::compile(parse& parse, linker& import) {
@ -1101,19 +1068,23 @@ const error& codegen::compile(parse& parse, linker& import) {
// size out of bound check
if (num_res.size()>0xffffff) {
err.load(file[0]); // load main execute file
err.err("code", "too many constant numbers: "+std::to_string(num_res.size()));
err.err("code",
"too many constant numbers: " + std::to_string(num_res.size()));
}
if (str_res.size()>0xffffff) {
err.load(file[0]); // load main execute file
err.err("code", "too many constant strings: "+std::to_string(str_res.size()));
err.err("code",
"too many constant strings: " + std::to_string(str_res.size()));
}
if (global.size()>=STACK_DEPTH) {
err.load(file[0]); // load main execute file
err.err("code", "too many global variants: "+std::to_string(global.size()));
err.err("code",
"too many global variants: " + std::to_string(global.size()));
}
if (code.size()>0xffffff) {
err.load(file[0]); // load main execute file
err.err("code", "bytecode size overflow: "+std::to_string(code.size()));
err.err("code",
"bytecode size overflow: " + std::to_string(code.size()));
}
return err;
}
@ -1125,12 +1096,12 @@ void codegen::print() {
// print const numbers
for(auto num : num_res) {
std::cout<<" .number "<<num<<"\n";
std::cout << " .number " << num << "\n";
}
// print const strings
for(const auto& str : str_res) {
std::cout<<" .symbol \""<<rawstr(str)<<"\"\n";
std::cout << " .symbol \"" << rawstr(str) << "\"\n";
}
// print code
@ -1140,7 +1111,7 @@ void codegen::print() {
// print opcode index, opcode name, opcode immediate number
const auto& c = code[i];
if (!festk.empty() && i==festk.top()) {
std::cout<<std::hex<<"<0x"<<fbstk.top()<<std::dec<<">;\n";
std::cout << std::hex << "<0x" << fbstk.top() << std::dec << ">;\n";
// avoid two empty lines
if (c.op!=op_newf) {
std::cout<<"\n";
@ -1151,7 +1122,7 @@ void codegen::print() {
// get function begin index and end index
if (c.op==op_newf) {
std::cout<<std::hex<<"\nfunc <0x"<<i<<std::dec<<">:\n";
std::cout << std::hex << "\nfunc <0x" << i << std::dec << ">:\n";
for(u32 j = i; j<code.size(); ++j) {
if (code[j].op==op_jmp) {
fbstk.push(i);
@ -1162,6 +1133,6 @@ void codegen::print() {
}
// output bytecode
std::cout<<" "<<codestream(c,i)<<"\n";
std::cout << " " << codestream(c,i) << "\n";
}
}

View File

@ -83,8 +83,7 @@ private:
void while_gen(while_expr*);
void for_gen(for_expr*);
void expr_gen(expr*);
void forindex_gen(forei_expr*);
void foreach_gen(forei_expr*);
void forei_gen(forei_expr*);
void or_gen(binary_operator*);
void and_gen(binary_operator*);
void unary_gen(unary_operator*);

View File

@ -1,7 +1,7 @@
#pragma once
#ifndef __nasver
#define __nasver "10.1"
#define __nasver "11.0"
#endif
#include <cstdint>

View File

@ -14,6 +14,7 @@
#include <unordered_map>
#include <thread>
#include <cstdlib>
const u32 VM_RAW_AST = 1;
const u32 VM_AST = 1<<1;
@ -25,53 +26,67 @@ const u32 VM_DEBUG = 1<<6;
std::ostream& help(std::ostream& out) {
out
<<" ,--#-,\n"
<<"<3 / \\____\\ <3\n"
<<" |_|__A_|\n"
<< " ,--#-,\n"
<< "<3 / \\____\\ <3\n"
<< " |_|__A_|\n"
#ifdef _WIN32
<<"use command <chcp 65001> to use unicode.\n"
<< "use command <chcp 65001> to use unicode.\n"
#endif
<<"\nnasal <option>\n"
<<"option:\n"
<<" -h, --help | get help.\n"
<<"\nnasal [option] <file> [argv]\n"
<<"option:\n"
<<" -a, --ast | view ast (after link/optimize process).\n"
<<" --raw-ast | view ast without after-processing.\n"
<<" -c, --code | view bytecode.\n"
<<" -e, --exec | execute.\n"
<<" -t, --time | show execute time.\n"
<<" -d, --detail | get detail info.\n"
<<" -dbg, --debug | debug mode.\n"
<<"file:\n"
<<" <filename> | execute file.\n"
<<"argv:\n"
<<" <args> | cmd arguments used in program.\n";
<< "\nnasal <option>\n"
<< "option:\n"
<< " -h, --help | get help.\n"
<< " -v, --version | get version.\n"
<< "\nnasal [option] <file> [argv]\n"
<< "option:\n"
<< " -a, --ast | view ast after link/optimize process.\n"
<< " --raw-ast | view ast without after-processing.\n"
<< " -c, --code | view generated bytecode.\n"
<< " -e, --exec | execute directly.\n"
<< " -t, --time | show execute time.\n"
<< " -d, --detail | get detail info.\n"
<< " -dbg, --debug | debug mode.\n"
<< "file:\n"
<< " <filename> | execute file.\n"
<< "argv:\n"
<< " <args> | cmd arguments used in program.\n";
return out;
}
std::ostream& logo(std::ostream& out) {
out
<<" __ _\n"
<<" /\\ \\ \\__ _ ___ __ _| |\n"
<<" / \\/ / _` / __|/ _` | |\n"
<<" / /\\ / (_| \\__ \\ (_| | |\n"
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
<<"ver : "<<__nasver<<" ("<<__DATE__<<" "<<__TIME__<<")\n"
<<"std : c++ "<<__cplusplus<<"\n"
<<"core : "<<std::thread::hardware_concurrency()<<" core(s)\n"
<<"repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
<<"repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
<<"wiki : https://wiki.flightgear.org/Nasal_scripting_language\n"
<<"input <nasal -h> to get help .\n";
<< " __ _\n"
<< " /\\ \\ \\__ _ ___ __ _| |\n"
<< " / \\/ / _` / __|/ _` | |\n"
<< " / /\\ / (_| \\__ \\ (_| | |\n"
<< " \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
<< "ver : " << __nasver << " (" << __DATE__ << " " << __TIME__ << ")\n"
<< "std : c++ " << __cplusplus << "\n"
<< "core : " << std::thread::hardware_concurrency() << " core(s)\n"
<< "repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
<< "repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
<< "wiki : https://wiki.flightgear.org/Nasal_scripting_language\n"
<< "input <nasal -h> to get help .\n";
return out;
}
std::ostream& version(std::ostream& out) {
std::srand(std::time(nullptr));
f64 num = 0;
for(u32 i = 0; i<5; ++i) {
num = (num+rand())*(1.0/(RAND_MAX+1.0));
}
if (num<0.01) {
parse::easter_egg();
}
out << "version " << __nasver;
out << " (" << __DATE__ << " " << __TIME__ << ")\n";
}
[[noreturn]]
void err() {
std::cerr
<<"invalid argument(s).\n"
<<"use <nasal -h> to get help.\n";
<< "invalid argument(s).\n"
<< "use <nasal -h> to get help.\n";
std::exit(1);
}
@ -80,8 +95,8 @@ void execute(
const std::vector<std::string>& argv,
const u32 cmd) {
using clk=std::chrono::high_resolution_clock;
const auto den=clk::duration::period::den;
using clk = std::chrono::high_resolution_clock;
const auto den = clk::duration::period::den;
error err;
lexer lex(err);
@ -131,14 +146,14 @@ void execute(
// get running time
if (cmd&VM_TIME) {
f64 tm=(clk::now()-start).count()*1.0/den;
std::clog<<"process exited after "<<tm<<"s.\n\n";
std::clog << "process exited after " << tm << "s.\n\n";
}
}
i32 main(i32 argc, const char* argv[]) {
// output version info
if (argc<=1) {
std::clog<<logo;
std::clog << logo;
return 0;
}
@ -146,7 +161,9 @@ i32 main(i32 argc, const char* argv[]) {
if (argc==2) {
std::string s(argv[1]);
if (s=="-h" || s=="--help") {
std::clog<<help;
std::clog << help;
} else if (s=="-v" || s=="--version") {
std::clog << version;
} else if (s[0]!='-') {
execute(s, {}, VM_EXEC);
} else {
@ -171,14 +188,14 @@ i32 main(i32 argc, const char* argv[]) {
{"--debug", VM_DEBUG},
{"-dbg", VM_DEBUG}
};
u32 cmd=0;
std::string filename="";
u32 cmd = 0;
std::string filename = "";
std::vector<std::string> vm_argv;
for(i32 i=1; i<argc; ++i) {
for(i32 i = 1; i<argc; ++i) {
if (cmdlst.count(argv[i])) {
cmd|=cmdlst.at(argv[i]);
cmd |= cmdlst.at(argv[i]);
} else if (!filename.length()) {
filename=argv[i];
filename = argv[i];
} else {
vm_argv.push_back(argv[i]);
}
@ -186,6 +203,6 @@ i32 main(i32 argc, const char* argv[]) {
if (!filename.length()) {
err();
}
execute(filename, vm_argv, cmd?cmd:VM_EXEC);
execute(filename, vm_argv, cmd? cmd:VM_EXEC);
return 0;
}

View File

@ -20,7 +20,7 @@ const error& parse::compile(const lexer& lexer) {
return err;
}
void parse::easter_egg() const {
void parse::easter_egg() {
std::clog
<< " _,,,_ \n"
<< " .' `'. \n"

View File

@ -157,5 +157,5 @@ public:
}
}
const error& compile(const lexer&);
void easter_egg() const;
static void easter_egg();
};