4 Commits

Author SHA1 Message Date
ValKmjolnir
536baa0fe8 Merge branch 'master' into develop 2026-01-19 23:57:32 +08:00
ValKmjolnir
03ac911291 📝 adjust files 2025-10-24 20:08:51 +08:00
ValKmjolnir
72933f4bf6 finish caller
Signed-off-by: ValKmjolnir <lhk101lhk101@qq.com>
2025-10-24 00:03:43 +08:00
ValKmjolnir
f04996201a 🎨 prepare to impl caller 2025-10-23 00:06:16 +08:00
28 changed files with 3870 additions and 4081 deletions

View File

@@ -41,10 +41,10 @@ set(NASAL_OBJECT_SOURCE_FILE
${CMAKE_SOURCE_DIR}/src/util/fs.cpp ${CMAKE_SOURCE_DIR}/src/util/fs.cpp
${CMAKE_SOURCE_DIR}/src/util/gc_stat.cpp ${CMAKE_SOURCE_DIR}/src/util/gc_stat.cpp
${CMAKE_SOURCE_DIR}/src/util/util.cpp ${CMAKE_SOURCE_DIR}/src/util/util.cpp
${CMAKE_SOURCE_DIR}/src/ast_dumper.cpp ${CMAKE_SOURCE_DIR}/src/ast/ast_dumper.cpp
${CMAKE_SOURCE_DIR}/src/ast_format.cpp ${CMAKE_SOURCE_DIR}/src/ast/ast_format.cpp
${CMAKE_SOURCE_DIR}/src/ast_visitor.cpp ${CMAKE_SOURCE_DIR}/src/ast/ast_visitor.cpp
${CMAKE_SOURCE_DIR}/src/nasal_ast.cpp ${CMAKE_SOURCE_DIR}/src/ast/ast.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

281
makefile
View File

@@ -9,290 +9,10 @@ else
CXXFLAGS = -std=$(STD) -c -O3 -fPIC -I src CXXFLAGS = -std=$(STD) -c -O3 -fPIC -I src
endif endif
NASAL_HEADER = \
src/ast_dumper.h\
src/ast_visitor.h\
src/nasal_ast.h\
src/natives/builtin.h\
src/nasal_codegen.h\
src/nasal_dbg.h\
src/nasal_err.h\
src/nasal_gc.h\
src/nasal_import.h\
src/nasal_lexer.h\
src/nasal_opcode.h\
src/nasal_parse.h\
src/nasal_vm.h\
src/nasal_type.h\
src/nasal.h\
src/optimizer.h\
src/symbol_finder.h\
src/cli/cli.h\
src/natives/fg_props.h\
src/natives/bits_lib.h\
src/natives/io_lib.h\
src/natives/math_lib.h\
src/natives/dylib_lib.h\
src/natives/json_lib.h\
src/natives/unix_lib.h\
src/natives/coroutine.h\
src/natives/regex_lib.h\
src/natives/subprocess.h\
src/repl/repl.h\
src/util/fs.h\
src/util/util.h
NASAL_OBJECT = \
build/nasal_err.o\
build/nasal_ast.o\
build/ast_visitor.o\
build/bits_lib.o\
build/ast_dumper.o\
build/nasal_lexer.o\
build/nasal_parse.o\
build/nasal_import.o\
build/optimizer.o\
build/nasal_opcode.o\
build/symbol_finder.o\
build/nasal_codegen.o\
build/nasal_gc.o\
build/builtin.o\
build/fg_props.o\
build/io_lib.o\
build/math_lib.o\
build/unix_lib.o\
build/dylib_lib.o\
build/subprocess.o\
build/json_lib.o\
build/coroutine.o\
build/nasal_type.o\
build/nasal_vm.o\
build/nasal_dbg.o\
build/regex_lib.o\
build/repl.o\
build/cli.o\
build/fs.o\
build/util.o\
build/main.o
# for test
nasal: $(NASAL_OBJECT) | build
@if [ OS = "Darwin" ]; then\
$(CXX) $(NASAL_OBJECT) -O3 -o nasal -ldl -lpthread -stdlib=libc++ -static-libstdc++;\
else\
$(CXX) $(NASAL_OBJECT) -O3 -o nasal -ldl -lpthread;\
fi
nasal.exe: $(NASAL_OBJECT) | build
$(CXX) $(NASAL_OBJECT) -O3 -o nasal.exe
build:
@ if [ ! -d build ]; then mkdir build; fi
build/main.o: $(NASAL_HEADER) src/main.cpp | build
$(CXX) $(CXXFLAGS) src/main.cpp -o build/main.o
build/cli.o: src/cli/cli.h src/cli/cli.cpp | build
$(CXX) $(CXXFLAGS) src/cli/cli.cpp -o build/cli.o
build/util.o: src/util/util.h src/util/util.cpp | build
$(CXX) $(CXXFLAGS) src/util/util.cpp -o build/util.o
build/fs.o: src/nasal.h src/util/util.h src/util/fs.h src/util/fs.cpp | build
$(CXX) $(CXXFLAGS) src/util/fs.cpp -o build/fs.o
build/repl.o: $(NASAL_HEADER) src/repl/repl.h src/repl/repl.cpp | build
$(CXX) $(CXXFLAGS) src/repl/repl.cpp -o build/repl.o
build/nasal_err.o: src/nasal.h src/repl/repl.h src/nasal_err.h src/nasal_err.cpp | build
$(CXX) $(CXXFLAGS) src/nasal_err.cpp -o build/nasal_err.o
build/nasal_type.o:\
src/nasal.h\
src/util/util.h\
src/nasal_type.h src/nasal_type.cpp | build
$(CXX) $(CXXFLAGS) src/nasal_type.cpp -o build/nasal_type.o
build/nasal_gc.o:\
src/nasal.h\
src/util/util.h\
src/nasal_type.h\
src/nasal_gc.h\
src/nasal_gc.cpp | build
$(CXX) $(CXXFLAGS) src/nasal_gc.cpp -o build/nasal_gc.o
build/nasal_import.o: \
src/nasal.h\
src/nasal_ast.h\
src/nasal_lexer.h\
src/nasal_parse.h\
src/util/util.h\
src/util/fs.h\
src/nasal_import.h src/nasal_import.cpp | build
$(CXX) $(CXXFLAGS) src/nasal_import.cpp -o build/nasal_import.o
build/nasal_lexer.o: \
src/nasal.h\
src/repl/repl.h\
src/util/util.h\
src/util/fs.h\
src/nasal_err.h\
src/nasal_lexer.h src/nasal_lexer.cpp | build
$(CXX) $(CXXFLAGS) src/nasal_lexer.cpp -o build/nasal_lexer.o
build/nasal_ast.o: \
src/nasal.h\
src/nasal_err.h\
src/nasal_ast.h src/nasal_ast.cpp | build
$(CXX) $(CXXFLAGS) src/nasal_ast.cpp -o build/nasal_ast.o
build/builtin.o: \
src/nasal.h\
src/nasal_type.h\
src/nasal_gc.h\
src/util/util.h\
src/natives/builtin.h\
src/natives/builtin.cpp | build
$(CXX) $(CXXFLAGS) src/natives/builtin.cpp -o build/builtin.o
build/coroutine.o: \
src/nasal.h\
src/nasal_type.h\
src/nasal_gc.h\
src/natives/coroutine.h src/natives/coroutine.cpp | build
$(CXX) $(CXXFLAGS) src/natives/coroutine.cpp -o build/coroutine.o
build/bits_lib.o: \
src/nasal.h\
src/nasal_type.h\
src/nasal_gc.h\
src/natives/bits_lib.h src/natives/bits_lib.cpp | build
$(CXX) $(CXXFLAGS) src/natives/bits_lib.cpp -o build/bits_lib.o
build/math_lib.o: \
src/nasal.h\
src/nasal_type.h\
src/nasal_gc.h\
src/natives/math_lib.h src/natives/math_lib.cpp | build
$(CXX) $(CXXFLAGS) src/natives/math_lib.cpp -o build/math_lib.o
build/io_lib.o: \
src/nasal.h\
src/nasal_type.h\
src/nasal_gc.h\
src/util/fs.h\
src/natives/io_lib.h src/natives/io_lib.cpp | build
$(CXX) $(CXXFLAGS) src/natives/io_lib.cpp -o build/io_lib.o
build/dylib_lib.o: \
src/nasal.h\
src/nasal_type.h\
src/nasal_gc.h\
src/util/util.h\
src/util/fs.h\
src/natives/dylib_lib.h src/natives/dylib_lib.cpp | build
$(CXX) $(CXXFLAGS) src/natives/dylib_lib.cpp -o build/dylib_lib.o
build/json_lib.o: \
src/nasal.h\
src/nasal_type.h\
src/nasal_gc.h\
src/util/util.h\
src/natives/json_lib.h src/natives/json_lib.cpp | build
$(CXX) $(CXXFLAGS) src/natives/json_lib.cpp -o build/json_lib.o
build/unix_lib.o: \
src/nasal.h\
src/nasal_type.h\
src/nasal_gc.h\
src/natives/unix_lib.h src/natives/unix_lib.cpp | build
$(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/subprocess.o: \
src/nasal.h\
src/nasal_type.h\
src/nasal_gc.h\
src/natives/subprocess.h src/natives/subprocess.cpp | build
$(CXX) $(CXXFLAGS) src/natives/subprocess.cpp -o build/subprocess.o
build/fg_props.o: \
src/nasal.h\
src/nasal_type.h\
src/nasal_gc.h\
src/natives/fg_props.h src/natives/fg_props.cpp | build
$(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
$(CXX) $(CXXFLAGS) src/nasal_codegen.cpp -o build/nasal_codegen.o
build/nasal_opcode.o: \
src/nasal.h\
src/natives/builtin.h\
src/util/util.h\
src/nasal_opcode.h src/nasal_opcode.cpp | build
$(CXX) $(CXXFLAGS) src/nasal_opcode.cpp -o build/nasal_opcode.o
build/nasal_parse.o: \
src/nasal.h\
src/nasal_ast.h\
src/nasal_lexer.h\
src/nasal_err.h\
src/util/util.h\
src/nasal_parse.h src/nasal_parse.cpp src/nasal_ast.h | build
$(CXX) $(CXXFLAGS) src/nasal_parse.cpp -o build/nasal_parse.o
build/optimizer.o: \
src/nasal.h\
src/nasal_err.h\
src/nasal_ast.h\
src/ast_visitor.h\
src/optimizer.h src/optimizer.cpp src/nasal_ast.h | build
$(CXX) $(CXXFLAGS) src/optimizer.cpp -o build/optimizer.o
build/symbol_finder.o: \
src/nasal.h\
src/nasal_err.h\
src/nasal_ast.h\
src/ast_visitor.h\
src/symbol_finder.h src/symbol_finder.cpp src/nasal_ast.h | build
$(CXX) $(CXXFLAGS) src/symbol_finder.cpp -o build/symbol_finder.o
build/ast_visitor.o: \
src/nasal.h\
src/nasal_err.h\
src/nasal_ast.h\
src/ast_visitor.h src/ast_visitor.cpp | build
$(CXX) $(CXXFLAGS) src/ast_visitor.cpp -o build/ast_visitor.o
build/ast_dumper.o: \
src/nasal.h\
src/nasal_err.h\
src/nasal_ast.h\
src/ast_visitor.h\
src/util/util.h\
src/ast_dumper.h src/ast_dumper.cpp | build
$(CXX) $(CXXFLAGS) src/ast_dumper.cpp -o build/ast_dumper.o
build/nasal_vm.o: $(NASAL_HEADER) src/nasal_vm.h src/nasal_vm.cpp | build
$(CXX) $(CXXFLAGS) src/nasal_vm.cpp -o build/nasal_vm.o
build/nasal_dbg.o: $(NASAL_HEADER) src/nasal_dbg.h src/nasal_dbg.cpp | build
$(CXX) $(CXXFLAGS) src/nasal_dbg.cpp -o build/nasal_dbg.o
.PHONY: clean .PHONY: clean
clean: clean:
@ echo "[clean] nasal" && if [ -e nasal ]; then rm nasal; fi @ echo "[clean] nasal" && if [ -e nasal ]; then rm nasal; fi
@ echo "[clean] nasal.exe" && if [ -e nasal.exe ]; then rm nasal.exe; fi @ echo "[clean] nasal.exe" && if [ -e nasal.exe ]; then rm nasal.exe; fi
@ rm $(NASAL_OBJECT)
.PHONY: test .PHONY: test
test: test:
@@ -303,6 +23,7 @@ test:
@ ./nasal -t test/bigloop.nas @ ./nasal -t test/bigloop.nas
@ ./nasal -t test/bp.nas @ ./nasal -t test/bp.nas
@ ./nasal -d test/calc.nas @ ./nasal -d test/calc.nas
@ ./nasal test/caller.nas
@ ./nasal -e test/choice.nas @ ./nasal -e test/choice.nas
@ ./nasal -e test/class.nas @ ./nasal -e test/class.nas
@ ./nasal -t -d test/console3D.nas 20 @ ./nasal -t -d test/console3D.nas 20

View File

@@ -1,4 +1,4 @@
#include "nasal_ast.h" #include "ast.h"
#include "ast_visitor.h" #include "ast_visitor.h"
namespace nasal { namespace nasal {

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include "nasal_ast.h" #include "ast.h"
namespace nasal { namespace nasal {

View File

@@ -1,10 +1,10 @@
#include "nasal.h" #include "nasal.h"
#include "nasal_lexer.h" #include "nasal_lexer.h"
#include "nasal_ast.h" #include "ast/ast.h"
#include "nasal_parse.h" #include "nasal_parse.h"
#include "util/util.h" #include "util/util.h"
#include "cli/cli.h" #include "cli/cli.h"
#include "ast_format.h" #include "ast/ast_format.h"
#include <iostream> #include <iostream>
#include <thread> #include <thread>

View File

@@ -3,11 +3,11 @@
#include "nasal_gc.h" #include "nasal_gc.h"
#include "nasal_err.h" #include "nasal_err.h"
#include "nasal_lexer.h" #include "nasal_lexer.h"
#include "nasal_ast.h" #include "ast/ast.h"
#include "ast/ast_visitor.h"
#include "ast/ast_dumper.h"
#include "nasal_parse.h" #include "nasal_parse.h"
#include "nasal_import.h" #include "nasal_import.h"
#include "ast_visitor.h"
#include "ast_dumper.h"
#include "symbol_finder.h" #include "symbol_finder.h"
#include "optimizer.h" #include "optimizer.h"
#include "nasal_codegen.h" #include "nasal_codegen.h"

View File

@@ -2,8 +2,8 @@
#include "nasal_err.h" #include "nasal_err.h"
#include "nasal_opcode.h" #include "nasal_opcode.h"
#include "nasal_ast.h" #include "ast/ast.h"
#include "ast_visitor.h" #include "ast/ast_visitor.h"
#include "symbol_finder.h" #include "symbol_finder.h"
#include "nasal_parse.h" #include "nasal_parse.h"
#include "nasal_import.h" #include "nasal_import.h"

View File

@@ -9,7 +9,7 @@
#endif #endif
#include "nasal.h" #include "nasal.h"
#include "nasal_ast.h" #include "ast/ast.h"
#include "nasal_lexer.h" #include "nasal_lexer.h"
#include "nasal_parse.h" #include "nasal_parse.h"
#include "symbol_finder.h" #include "symbol_finder.h"

View File

@@ -103,94 +103,94 @@ enum opcode_type: u8 {
}; };
static std::unordered_map<opcode_type, std::string> operand_name_table = { static std::unordered_map<opcode_type, std::string> operand_name_table = {
{opcode_type::op_exit, "exit "}, {opcode_type::op_exit, "exit "},
{opcode_type::op_repl, "repl "}, {opcode_type::op_repl, "repl "},
{opcode_type::op_intl, "intl "}, {opcode_type::op_intl, "intl "},
{opcode_type::op_loadg, "loadg "}, {opcode_type::op_loadg, "loadg "},
{opcode_type::op_loadl, "loadl "}, {opcode_type::op_loadl, "loadl "},
{opcode_type::op_loadu, "loadu "}, {opcode_type::op_loadu, "loadu "},
{opcode_type::op_dup, "dup "}, {opcode_type::op_dup, "dup "},
{opcode_type::op_pnum, "pnum "}, {opcode_type::op_pnum, "pnum "},
{opcode_type::op_pnil, "pnil "}, {opcode_type::op_pnil, "pnil "},
{opcode_type::op_pstr, "pstr "}, {opcode_type::op_pstr, "pstr "},
{opcode_type::op_newv, "newv "}, {opcode_type::op_newv, "newv "},
{opcode_type::op_newh, "newh "}, {opcode_type::op_newh, "newh "},
{opcode_type::op_newf, "newf "}, {opcode_type::op_newf, "newf "},
{opcode_type::op_happ, "happ "}, {opcode_type::op_happ, "happ "},
{opcode_type::op_para, "para "}, {opcode_type::op_para, "para "},
{opcode_type::op_deft, "def "}, {opcode_type::op_deft, "def "},
{opcode_type::op_dyn, "dyn "}, {opcode_type::op_dyn, "dyn "},
{opcode_type::op_lnot, "lnot "}, {opcode_type::op_lnot, "lnot "},
{opcode_type::op_usub, "usub "}, {opcode_type::op_usub, "usub "},
{opcode_type::op_bnot, "bitnot"}, {opcode_type::op_bnot, "bitnot"},
{opcode_type::op_btor, "bitor "}, {opcode_type::op_btor, "bitor "},
{opcode_type::op_btxor, "bitxor"}, {opcode_type::op_btxor, "bitxor"},
{opcode_type::op_btand, "bitand"}, {opcode_type::op_btand, "bitand"},
{opcode_type::op_add, "add "}, {opcode_type::op_add, "add "},
{opcode_type::op_sub, "sub "}, {opcode_type::op_sub, "sub "},
{opcode_type::op_mul, "mult "}, {opcode_type::op_mul, "mult "},
{opcode_type::op_div, "div "}, {opcode_type::op_div, "div "},
{opcode_type::op_lnk, "lnk "}, {opcode_type::op_lnk, "lnk "},
{opcode_type::op_addc, "addc "}, {opcode_type::op_addc, "addc "},
{opcode_type::op_subc, "subc "}, {opcode_type::op_subc, "subc "},
{opcode_type::op_mulc, "multc "}, {opcode_type::op_mulc, "multc "},
{opcode_type::op_divc, "divc "}, {opcode_type::op_divc, "divc "},
{opcode_type::op_lnkc, "lnkc "}, {opcode_type::op_lnkc, "lnkc "},
{opcode_type::op_addeq, "addeq "}, {opcode_type::op_addeq, "addeq "},
{opcode_type::op_subeq, "subeq "}, {opcode_type::op_subeq, "subeq "},
{opcode_type::op_muleq, "muleq "}, {opcode_type::op_muleq, "muleq "},
{opcode_type::op_diveq, "diveq "}, {opcode_type::op_diveq, "diveq "},
{opcode_type::op_lnkeq, "lnkeq "}, {opcode_type::op_lnkeq, "lnkeq "},
{opcode_type::op_btandeq, "bandeq"}, {opcode_type::op_btandeq, "bandeq"},
{opcode_type::op_btoreq, "boreq "}, {opcode_type::op_btoreq, "boreq "},
{opcode_type::op_btxoreq, "bxoreq"}, {opcode_type::op_btxoreq, "bxoreq"},
{opcode_type::op_addeqc, "addeqc"}, {opcode_type::op_addeqc, "addeqc"},
{opcode_type::op_subeqc, "subeqc"}, {opcode_type::op_subeqc, "subeqc"},
{opcode_type::op_muleqc, "muleqc"}, {opcode_type::op_muleqc, "muleqc"},
{opcode_type::op_diveqc, "diveqc"}, {opcode_type::op_diveqc, "diveqc"},
{opcode_type::op_lnkeqc, "lnkeqc"}, {opcode_type::op_lnkeqc, "lnkeqc"},
{opcode_type::op_addecp, "addecp"}, {opcode_type::op_addecp, "addecp"},
{opcode_type::op_subecp, "subecp"}, {opcode_type::op_subecp, "subecp"},
{opcode_type::op_mulecp, "mulecp"}, {opcode_type::op_mulecp, "mulecp"},
{opcode_type::op_divecp, "divecp"}, {opcode_type::op_divecp, "divecp"},
{opcode_type::op_lnkecp, "lnkecp"}, {opcode_type::op_lnkecp, "lnkecp"},
{opcode_type::op_meq, "meq "}, {opcode_type::op_meq, "meq "},
{opcode_type::op_eq, "eq "}, {opcode_type::op_eq, "eq "},
{opcode_type::op_neq, "neq "}, {opcode_type::op_neq, "neq "},
{opcode_type::op_less, "less "}, {opcode_type::op_less, "less "},
{opcode_type::op_leq, "leq "}, {opcode_type::op_leq, "leq "},
{opcode_type::op_grt, "grt "}, {opcode_type::op_grt, "grt "},
{opcode_type::op_geq, "geq "}, {opcode_type::op_geq, "geq "},
{opcode_type::op_lessc, "lessc "}, {opcode_type::op_lessc, "lessc "},
{opcode_type::op_leqc, "leqc "}, {opcode_type::op_leqc, "leqc "},
{opcode_type::op_grtc, "grtc "}, {opcode_type::op_grtc, "grtc "},
{opcode_type::op_geqc, "geqc "}, {opcode_type::op_geqc, "geqc "},
{opcode_type::op_pop, "pop "}, {opcode_type::op_pop, "pop "},
{opcode_type::op_jmp, "jmp "}, {opcode_type::op_jmp, "jmp "},
{opcode_type::op_jt, "jt "}, {opcode_type::op_jt, "jt "},
{opcode_type::op_jf, "jf "}, {opcode_type::op_jf, "jf "},
{opcode_type::op_cnt, "cnt "}, {opcode_type::op_cnt, "cnt "},
{opcode_type::op_findex, "findx "}, {opcode_type::op_findex, "findx "},
{opcode_type::op_feach, "feach "}, {opcode_type::op_feach, "feach "},
{opcode_type::op_callg, "callg "}, {opcode_type::op_callg, "callg "},
{opcode_type::op_calll, "calll "}, {opcode_type::op_calll, "calll "},
{opcode_type::op_upval, "upval "}, {opcode_type::op_upval, "upval "},
{opcode_type::op_callv, "callv "}, {opcode_type::op_callv, "callv "},
{opcode_type::op_callvi, "callvi"}, {opcode_type::op_callvi, "callvi"},
{opcode_type::op_callh, "callh "}, {opcode_type::op_callh, "callh "},
{opcode_type::op_callfv, "callfv"}, {opcode_type::op_callfv, "callfv"},
{opcode_type::op_callfh, "callfh"}, {opcode_type::op_callfh, "callfh"},
{opcode_type::op_callb, "callb "}, {opcode_type::op_callb, "callb "},
{opcode_type::op_slcbeg, "slcbeg"}, {opcode_type::op_slcbeg, "slcbeg"},
{opcode_type::op_slcend, "slcend"}, {opcode_type::op_slcend, "slcend"},
{opcode_type::op_slc, "slice "}, {opcode_type::op_slc, "slice "},
{opcode_type::op_slc2, "slice2"}, {opcode_type::op_slc2, "slice2"},
{opcode_type::op_mcallg, "mcallg"}, {opcode_type::op_mcallg, "mcallg"},
{opcode_type::op_mcalll, "mcalll"}, {opcode_type::op_mcalll, "mcalll"},
{opcode_type::op_mupval, "mupval"}, {opcode_type::op_mupval, "mupval"},
{opcode_type::op_mcallv, "mcallv"}, {opcode_type::op_mcallv, "mcallv"},
{opcode_type::op_mcallh, "mcallh"}, {opcode_type::op_mcallh, "mcallh"},
{opcode_type::op_ret, "ret "} {opcode_type::op_ret, "ret "}
}; };
struct opcode { struct opcode {

View File

@@ -1,4 +1,4 @@
#include "nasal_ast.h" #include "ast/ast.h"
#include "nasal_parse.h" #include "nasal_parse.h"
#include "util/util.h" #include "util/util.h"

View File

@@ -3,7 +3,7 @@
#include <unordered_map> #include <unordered_map>
#include "nasal.h" #include "nasal.h"
#include "nasal_ast.h" #include "ast/ast.h"
#include "nasal_lexer.h" #include "nasal_lexer.h"
#include "nasal_err.h" #include "nasal_err.h"

View File

@@ -159,25 +159,6 @@ std::ostream& operator<<(std::ostream& out, const nas_ghost& ghost) {
return out; return out;
} }
void nas_co::clear() {
if (!ctx.stack) {
return;
}
for (u32 i = 0; i<VM_STACK_DEPTH; ++i) {
ctx.stack[i] = var::nil();
}
ctx.pc = 0;
ctx.localr = nullptr;
ctx.memr = nullptr;
ctx.canary = ctx.stack+VM_STACK_DEPTH-1;
ctx.top = ctx.stack;
ctx.funcr = var::nil();
ctx.upvalr = var::nil();
status = status::suspended;
}
std::ostream& operator<<(std::ostream& out, const nas_co& co) { std::ostream& operator<<(std::ostream& out, const nas_co& co) {
out << "<coroutine at 0x" << std::hex; out << "<coroutine at 0x" << std::hex;
out << reinterpret_cast<u64>(&co) << std::dec << ">"; out << reinterpret_cast<u64>(&co) << std::dec << ">";

View File

@@ -298,6 +298,12 @@ public:
T convert() const { return reinterpret_cast<T>(pointer); } T convert() const { return reinterpret_cast<T>(pointer); }
}; };
struct callsite {
var caller;
u64 file_index = 0;
u64 line = 0;
};
struct context { struct context {
u64 pc = 0; u64 pc = 0;
var* localr = nullptr; var* localr = nullptr;
@@ -305,8 +311,43 @@ struct context {
var funcr = var::nil(); var funcr = var::nil();
var upvalr = var::nil(); var upvalr = var::nil();
var* canary = nullptr; var* canary = nullptr;
var* stack = nullptr; var* stack = nullptr;
var* top = nullptr; var* top = nullptr;
callsite* func_stack = nullptr;
callsite* func_top = nullptr;
const std::string* files = nullptr;
void ctor() {
stack = new var[VM_STACK_DEPTH];
func_stack = new callsite[VM_STACK_DEPTH];
}
void dtor() {
delete[] stack;
delete[] func_stack;
}
void clear() {
/* set canary and program counter */
pc = 0;
localr = nullptr;
memr = nullptr;
funcr = var::nil();
upvalr = var::nil();
/* set canary = stack[VM_STACK_DEPTH-1] */
canary = stack + VM_STACK_DEPTH - 1;
/* nothing is on stack */
top = stack;
func_top = func_stack - 1;
/* clear main stack */
for (u32 i = 0; i < VM_STACK_DEPTH; ++i) {
stack[i] = var::nil();
}
}
}; };
struct nas_co { struct nas_co {
@@ -319,14 +360,9 @@ struct nas_co {
context ctx; context ctx;
status status; status status;
nas_co() { nas_co() { ctx.ctor(); }
ctx.stack = new var[VM_STACK_DEPTH]; ~nas_co() { ctx.dtor(); }
clear(); void clear() { ctx.clear(); status = status::suspended; }
}
~nas_co() {
delete[] ctx.stack;
}
void clear();
friend std::ostream& operator<<(std::ostream&, const nas_co&); friend std::ostream& operator<<(std::ostream&, const nas_co&);
}; };

View File

@@ -45,22 +45,11 @@ void vm::vm_init_enrty(const std::vector<std::string>& strs,
} }
void vm::context_and_global_init() { void vm::context_and_global_init() {
/* set canary and program counter */ /* clear context status */
ctx.pc = 0; ctx.clear();
ctx.localr = nullptr;
ctx.memr = nullptr;
ctx.funcr = nil;
ctx.upvalr = nil;
/* set canary = stack[VM_STACK_DEPTH-1] */
ctx.canary = ctx.stack+VM_STACK_DEPTH-1;
/* nothing is on stack */
ctx.top = ctx.stack - 1;
/* clear main stack and global */ /* clear main stack and global */
for (u32 i = 0; i<VM_STACK_DEPTH; ++i) { for (u32 i = 0; i < VM_STACK_DEPTH; ++i) {
ctx.stack[i] = nil;
global[i] = nil; global[i] = nil;
} }
} }

View File

@@ -287,11 +287,11 @@ public:
/* constructor of vm instance */ /* constructor of vm instance */
vm() { vm() {
ctx.stack = new var[VM_STACK_DEPTH]; ctx.ctor();
global = new var[VM_STACK_DEPTH]; global = new var[VM_STACK_DEPTH];
} }
~vm() { ~vm() {
delete[] ctx.stack; ctx.dtor();
delete[] global; delete[] global;
} }
@@ -900,6 +900,11 @@ inline void vm::o_callfv() {
var tmp = local[-1]; var tmp = local[-1];
local[-1] = ctx.funcr; local[-1] = ctx.funcr;
ctx.funcr = tmp; ctx.funcr = tmp;
(++ctx.func_top)[0] = {
tmp,
bytecode[ctx.pc].fidx,
bytecode[ctx.pc].line
};
// top-argc+lsize(local) +1(old pc) +1(old localr) +1(old upvalr) // top-argc+lsize(local) +1(old pc) +1(old localr) +1(old upvalr)
if (ctx.top-argc+func.local_size+3>=ctx.canary) { if (ctx.top-argc+func.local_size+3>=ctx.canary) {
@@ -969,6 +974,11 @@ inline void vm::o_callfh() {
var tmp = ctx.top[-1]; var tmp = ctx.top[-1];
ctx.top[-1] = ctx.funcr; ctx.top[-1] = ctx.funcr;
ctx.funcr = tmp; ctx.funcr = tmp;
(++ctx.func_top)[0] = {
tmp,
bytecode[ctx.pc].fidx,
bytecode[ctx.pc].line
};
// top -1(hash) +lsize(local) +1(old pc) +1(old localr) +1(old upvalr) // top -1(hash) +lsize(local) +1(old pc) +1(old localr) +1(old upvalr)
if (ctx.top+func.local_size+2>= ctx.canary) { if (ctx.top+func.local_size+2>= ctx.canary) {
@@ -1011,6 +1021,9 @@ inline void vm::o_callb() {
// this code is written for coroutine // this code is written for coroutine
(++ctx.top)[0] = nil; (++ctx.top)[0] = nil;
// set file list into ctx
ctx.files = files;
// if running a native function about coroutine // if running a native function about coroutine
// (top) will be set to another context.top, instead of main_context.top // (top) will be set to another context.top, instead of main_context.top
auto function_pointer = native_function[imm[ctx.pc]].func; auto function_pointer = native_function[imm[ctx.pc]].func;
@@ -1212,6 +1225,7 @@ inline void vm::o_ret() {
ctx.top = local-1; ctx.top = local-1;
ctx.funcr = ctx.top[0]; ctx.funcr = ctx.top[0];
ctx.top[0] = ret; // rewrite func with returned value ctx.top[0] = ret; // rewrite func with returned value
ctx.func_top--;
// synchronize upvalue // synchronize upvalue
if (up.is_upval()) { if (up.is_upval()) {

View File

@@ -528,6 +528,26 @@ var builtin_version(context* ctx, gc* ngc) {
return ngc->newstr(__nasver__); return ngc->newstr(__nasver__);
} }
var builtin_caller(context* ctx, gc* ngc) {
auto level = ctx->localr[1];
if (!level.is_num()) {
return nil;
}
auto level_num = static_cast<i64>(level.num());
if (ctx->func_top - level_num - 1 < ctx->func_stack) {
return nil;
}
const auto& cs = ctx->func_top[-level_num - 1];
var res = ngc->temp = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(ngc->alloc(vm_type::vm_hash));
res.vec().elems.push_back(cs.caller);
res.vec().elems.push_back(ngc->newstr(ctx->files[cs.file_index]));
res.vec().elems.push_back(var::num(cs.line));
ngc->temp = nil;
return res;
}
var builtin_arch(context* ctx, gc* ngc) { var builtin_arch(context* ctx, gc* ngc) {
return ngc->newstr(util::get_arch()); return ngc->newstr(util::get_arch());
} }
@@ -840,6 +860,7 @@ nasal_builtin_table builtin[] = {
{"__platform", builtin_platform}, {"__platform", builtin_platform},
{"__arch", builtin_arch}, {"__arch", builtin_arch},
{"__version", builtin_version}, {"__version", builtin_version},
{"__caller", builtin_caller},
{"__md5", builtin_md5}, {"__md5", builtin_md5},
{"__maketimestamp", builtin_maketimestamp}, {"__maketimestamp", builtin_maketimestamp},
{"__time_stamp", builtin_time_stamp}, {"__time_stamp", builtin_time_stamp},

View File

@@ -69,6 +69,8 @@ var builtin_platform(context*, gc*);
var builtin_arch(context*, gc*); var builtin_arch(context*, gc*);
var builtin_version(context*, gc*); var builtin_version(context*, gc*);
var builtin_caller(context*, gc*);
// md5 related functions // md5 related functions
std::string tohex(u32); std::string tohex(u32);
std::string md5(const std::string&); std::string md5(const std::string&);

View File

@@ -2,8 +2,8 @@
#include <cmath> #include <cmath>
#include "nasal_ast.h" #include "ast/ast.h"
#include "ast_visitor.h" #include "ast/ast_visitor.h"
namespace nasal { namespace nasal {

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include "nasal_ast.h" #include "ast/ast.h"
#include "ast_visitor.h" #include "ast/ast_visitor.h"
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>

View File

@@ -385,7 +385,8 @@ var call = func(function, args = nil, _me = nil, locals = nil, error = nil) {
} }
var caller = func(level = 1) { var caller = func(level = 1) {
die("this runtime does not support caller"); # TODO: caller should return [scope, func, call location file, call location line]
return __caller(level);
} }
var closure = func(function, level = 1) { var closure = func(function, level = 1) {

24
test/caller.nas Normal file
View File

@@ -0,0 +1,24 @@
var a = func(x, y, z) {
for (var i = 0; i < 20; i += 1) {
var cl = caller(i);
if (cl == nil) {
return;
}
print("[", i, "]\t", cl[1], "\t -> called from ", cl[2], ":", cl[3], "\n");
}
}
var b = func(x, y) {
a(1, 2, 3);
}
var c = func(x) b(1, 2);
var d = func c(1);
var e = func d();
var f = func e();
var g = func f();
var h = func g();
var i = func h();
var j = func i();
j();

View File

@@ -109,7 +109,7 @@ for (var t = 0; t < 10; t += 1) {
counter += 1; counter += 1;
for (var i = 0; i < t + 1; i += 1) for (var i = 0; i < t + 1; i += 1)
coroutine.resume(co); coroutine.resume(co);
if (counter - int(counter / 1000) * 1000 == 0) { if (counter - int(counter / 2500) * 2500 == 0) {
var rate = counter / 2e5; var rate = counter / 2e5;
print(" ", bar.bar(rate), " ", print(" ", bar.bar(rate), " ",
padding.leftpad(str(int(rate*100)),3), "% | ", padding.leftpad(str(int(rate*100)),3), "% | ",
@@ -120,7 +120,7 @@ for (var t = 0; t < 10; t += 1) {
} }
tm.stamp(); tm.stamp();
for (var i = 0; i < 1e5; i += 1) for (var i = 0; i < 2e5; i += 1)
consumer(); consumer();
println(" ", bar.bar(1), " 100% | ", println(" ", bar.bar(1), " 100% | ",
str(int(1e3 * counter / tm.elapsedMSec())), str(int(1e3 * counter / tm.elapsedMSec())),