🎨 fix typo in report info
This commit is contained in:
parent
21911f21f0
commit
cf2323623b
|
@ -56,12 +56,14 @@ target_include_directories(nasal-object PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||||
# build nasal
|
# build nasal
|
||||||
add_executable(nasal ${CMAKE_SOURCE_DIR}/src/main.cpp)
|
add_executable(nasal ${CMAKE_SOURCE_DIR}/src/main.cpp)
|
||||||
target_link_libraries(nasal nasal-object)
|
target_link_libraries(nasal nasal-object)
|
||||||
|
|
||||||
# link ldl and lpthread
|
# link ldl and lpthread
|
||||||
if(NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
|
if(NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
|
||||||
target_link_libraries(nasal dl)
|
target_link_libraries(nasal dl)
|
||||||
target_link_libraries(nasal pthread)
|
target_link_libraries(nasal pthread)
|
||||||
endif()
|
endif()
|
||||||
target_include_directories(nasal PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
target_include_directories(nasal PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||||
|
|
||||||
# copy nasal from build dir to the outside dir
|
# copy nasal from build dir to the outside dir
|
||||||
if(NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
|
if(NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
|
|
@ -517,7 +517,7 @@ nasal_builtin_table builtin[] = {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
At last,warp the `__print` in a nasal file:
|
At last, wrap the `__print` up in a nasal file:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var print = func(elems...) {
|
var print = func(elems...) {
|
||||||
|
@ -534,7 +534,7 @@ var print = func(elems...) {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
If you don't warp built-in function in a normal nasal function,
|
If you don't wrap built-in function up in a normal nasal function,
|
||||||
this native function may cause __segmentation fault__ when searching arguments.
|
this native function may cause __segmentation fault__ when searching arguments.
|
||||||
|
|
||||||
Use `import("filename.nas")` to get the nasal file including your built-in functions, then you could use it.
|
Use `import("filename.nas")` to get the nasal file including your built-in functions, then you could use it.
|
||||||
|
|
|
@ -49,9 +49,7 @@ void codegen::check_id_exist(identifier* node) {
|
||||||
const auto& name = node->get_name();
|
const auto& name = node->get_name();
|
||||||
if (native_function_mapper.count(name)) {
|
if (native_function_mapper.count(name)) {
|
||||||
if (local.empty()) {
|
if (local.empty()) {
|
||||||
die("native function should not be used in global scope",
|
die("native function should not be used in global scope", node);
|
||||||
node->get_location()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -65,9 +63,9 @@ void codegen::check_id_exist(identifier* node) {
|
||||||
if (global_symbol_find(name)>=0) {
|
if (global_symbol_find(name)>=0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
die("undefined symbol \"" + name +
|
die("undefined symbol \""
|
||||||
"\", and this symbol is useless here",
|
+ name + "\", and this symbol is useless here",
|
||||||
node->get_location()
|
node
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,17 +92,18 @@ void codegen::regist_string(const std::string& str) {
|
||||||
void codegen::find_symbol(code_block* node) {
|
void codegen::find_symbol(code_block* node) {
|
||||||
auto finder = std::make_unique<symbol_finder>();
|
auto finder = std::make_unique<symbol_finder>();
|
||||||
for(const auto& i : finder->do_find(node)) {
|
for(const auto& i : finder->do_find(node)) {
|
||||||
|
const auto& file = i.pos_node->get_location().file;
|
||||||
// check if symbol conflicts with native function name
|
// check if symbol conflicts with native function name
|
||||||
if (native_function_mapper.count(i.name)) {
|
if (native_function_mapper.count(i.name)) {
|
||||||
die("symbol conflicts with native function", i.location);
|
die("symbol conflicts with native function", i.pos_node);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// create new namespace with checking existence of location file
|
// create new namespace with checking existence of location file
|
||||||
if (!nasal_namespace.count(i.location.file)) {
|
if (!nasal_namespace.count(file)) {
|
||||||
nasal_namespace[i.location.file] = {};
|
nasal_namespace[file] = {};
|
||||||
}
|
}
|
||||||
// if in global scope, load global symbol into this namespace
|
// if in global scope, load global symbol into this namespace
|
||||||
auto& scope = nasal_namespace.at(i.location.file);
|
auto& scope = nasal_namespace.at(file);
|
||||||
if (local.empty() && !scope.count(i.name)) {
|
if (local.empty() && !scope.count(i.name)) {
|
||||||
scope.insert(i.name);
|
scope.insert(i.name);
|
||||||
}
|
}
|
||||||
|
@ -223,22 +222,16 @@ void codegen::func_gen(function* node) {
|
||||||
if (checked_default &&
|
if (checked_default &&
|
||||||
tmp->get_parameter_type()!=
|
tmp->get_parameter_type()!=
|
||||||
parameter::kind::default_parameter) {
|
parameter::kind::default_parameter) {
|
||||||
die("must use default parameter here",
|
die("must use default parameter here", tmp);
|
||||||
tmp->get_location()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (checked_dynamic &&
|
if (checked_dynamic &&
|
||||||
tmp!=node->get_parameter_list().back()) {
|
tmp!=node->get_parameter_list().back()) {
|
||||||
die("dynamic parameter must be the last one",
|
die("dynamic parameter must be the last one", tmp);
|
||||||
tmp->get_location()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// check redefinition
|
// check redefinition
|
||||||
const auto& name = tmp->get_parameter_name();
|
const auto& name = tmp->get_parameter_name();
|
||||||
if (argname.count(name)) {
|
if (argname.count(name)) {
|
||||||
die("redefinition of parameter: " + name,
|
die("redefinition of parameter: " + name, tmp);
|
||||||
tmp->get_location()
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
argname[name] = true;
|
argname[name] = true;
|
||||||
}
|
}
|
||||||
|
@ -260,9 +253,7 @@ void codegen::func_gen(function* node) {
|
||||||
for(auto tmp : node->get_parameter_list()) {
|
for(auto tmp : node->get_parameter_list()) {
|
||||||
const auto& name = tmp->get_parameter_name();
|
const auto& name = tmp->get_parameter_name();
|
||||||
if (name=="me") {
|
if (name=="me") {
|
||||||
die("\"me\" should not be a parameter",
|
die("\"me\" should not be parameter", tmp);
|
||||||
tmp->get_location()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
regist_string(name);
|
regist_string(name);
|
||||||
switch(tmp->get_parameter_type()) {
|
switch(tmp->get_parameter_type()) {
|
||||||
|
@ -317,7 +308,7 @@ void codegen::func_gen(function* node) {
|
||||||
if (local.back().size()>=VM_STACK_DEPTH || local.back().size()>=UINT16_MAX) {
|
if (local.back().size()>=VM_STACK_DEPTH || local.back().size()>=UINT16_MAX) {
|
||||||
die("too many local variants: " +
|
die("too many local variants: " +
|
||||||
std::to_string(local.back().size()),
|
std::to_string(local.back().size()),
|
||||||
block->get_location()
|
block
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
local.pop_back();
|
local.pop_back();
|
||||||
|
@ -358,9 +349,7 @@ void codegen::call_identifier(identifier* node) {
|
||||||
node->get_location()
|
node->get_location()
|
||||||
);
|
);
|
||||||
if (local.empty()) {
|
if (local.empty()) {
|
||||||
die("should warp native function in local scope",
|
die("should wrap up native function in local scope", node);
|
||||||
node->get_location()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -378,7 +367,7 @@ void codegen::call_identifier(identifier* node) {
|
||||||
emit(op_callg, index, node->get_location());
|
emit(op_callg, index, node->get_location());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
die("undefined symbol \"" + name + "\"", node->get_location());
|
die("undefined symbol \"" + name + "\"", node);
|
||||||
// generation failed, put a push nil operand here to fill the space
|
// generation failed, put a push nil operand here to fill the space
|
||||||
emit(op_pnil, index, node->get_location());
|
emit(op_pnil, index, node->get_location());
|
||||||
}
|
}
|
||||||
|
@ -459,7 +448,7 @@ void codegen::call_func_gen(call_function* node) {
|
||||||
void codegen::mcall(expr* node) {
|
void codegen::mcall(expr* node) {
|
||||||
if (node->get_type()!=expr_type::ast_id &&
|
if (node->get_type()!=expr_type::ast_id &&
|
||||||
node->get_type()!=expr_type::ast_call) {
|
node->get_type()!=expr_type::ast_call) {
|
||||||
die("bad left-value: cannot get memory space", node->get_location());
|
die("bad left-value: cannot get memory space", node);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// generate symbol call if node is just ast_id and return
|
// generate symbol call if node is just ast_id and return
|
||||||
|
@ -492,18 +481,18 @@ void codegen::mcall(expr* node) {
|
||||||
case expr_type::ast_callv:
|
case expr_type::ast_callv:
|
||||||
mcall_vec(reinterpret_cast<call_vector*>(tmp)); break;
|
mcall_vec(reinterpret_cast<call_vector*>(tmp)); break;
|
||||||
case expr_type::ast_callf:
|
case expr_type::ast_callf:
|
||||||
die("bad left-value: function call", tmp->get_location()); break;
|
die("bad left-value: function call", tmp); break;
|
||||||
case expr_type::ast_null_access:
|
case expr_type::ast_null_access:
|
||||||
die("bad left-value: null access test", tmp->get_location()); break;
|
die("bad left-value: null access test", tmp); break;
|
||||||
default:
|
default:
|
||||||
die("bad left-value: unknown call", tmp->get_location()); break;
|
die("bad left-value: unknown call", tmp); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void codegen::mcall_identifier(identifier* node) {
|
void codegen::mcall_identifier(identifier* node) {
|
||||||
const auto& name = node->get_name();
|
const auto& name = node->get_name();
|
||||||
if (native_function_mapper.count(name)) {
|
if (native_function_mapper.count(name)) {
|
||||||
die("cannot modify native function", node->get_location());
|
die("cannot modify native function", node);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,17 +509,17 @@ void codegen::mcall_identifier(identifier* node) {
|
||||||
emit(op_mcallg, index, node->get_location());
|
emit(op_mcallg, index, node->get_location());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
die("undefined symbol \"" + name + "\"", node->get_location());
|
die("undefined symbol \"" + name + "\"", node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void codegen::mcall_vec(call_vector* node) {
|
void codegen::mcall_vec(call_vector* node) {
|
||||||
if (node->get_slices().size()>1) {
|
if (node->get_slices().size()>1) {
|
||||||
die("bad left-value: subvec call", node->get_location());
|
die("bad left-value: subvec call", node);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto call = node->get_slices()[0];
|
auto call = node->get_slices()[0];
|
||||||
if (call->get_end()) {
|
if (call->get_end()) {
|
||||||
die("bad left-value: subvec call", node->get_location());
|
die("bad left-value: subvec call", node);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
calc_gen(call->get_begin());
|
calc_gen(call->get_begin());
|
||||||
|
@ -566,14 +555,14 @@ void codegen::multi_def(definition_expr* node) {
|
||||||
die("lack values in multi-definition, expect " +
|
die("lack values in multi-definition, expect " +
|
||||||
std::to_string(identifiers.size()) + " but get " +
|
std::to_string(identifiers.size()) + " but get " +
|
||||||
std::to_string(vals.size()),
|
std::to_string(vals.size()),
|
||||||
node->get_tuple()->get_location()
|
node->get_tuple()
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
} else if (identifiers.size()<vals.size()) {
|
} else if (identifiers.size()<vals.size()) {
|
||||||
die("too many values in multi-definition, expect " +
|
die("too many values in multi-definition, expect " +
|
||||||
std::to_string(identifiers.size()) + " but get " +
|
std::to_string(identifiers.size()) + " but get " +
|
||||||
std::to_string(vals.size()),
|
std::to_string(vals.size()),
|
||||||
node->get_tuple()->get_location()
|
node->get_tuple()
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -600,7 +589,7 @@ void codegen::multi_def(definition_expr* node) {
|
||||||
|
|
||||||
void codegen::definition_gen(definition_expr* node) {
|
void codegen::definition_gen(definition_expr* node) {
|
||||||
if (node->get_variable_name() && node->get_tuple()) {
|
if (node->get_variable_name() && node->get_tuple()) {
|
||||||
die("cannot accept too many values", node->get_value()->get_location());
|
die("cannot accept too many values", node->get_value());
|
||||||
}
|
}
|
||||||
node->get_variable_name()? single_def(node):multi_def(node);
|
node->get_variable_name()? single_def(node):multi_def(node);
|
||||||
}
|
}
|
||||||
|
@ -724,7 +713,7 @@ void codegen::gen_assignment_equal_statement(assignment_expr* node) {
|
||||||
case op_mcallg: code.back().op = op_loadg; break;
|
case op_mcallg: code.back().op = op_loadg; break;
|
||||||
case op_mcalll: code.back().op = op_loadl; break;
|
case op_mcalll: code.back().op = op_loadl; break;
|
||||||
case op_mupval: code.back().op = op_loadu; break;
|
case op_mupval: code.back().op = op_loadu; break;
|
||||||
default: die("unexpected operand to replace", node->get_location());
|
default: die("unexpected operand to replace", node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -779,7 +768,7 @@ void codegen::multi_assign_gen(multi_assign* node) {
|
||||||
"lack value(s) in multi-assignment, expect " +
|
"lack value(s) in multi-assignment, expect " +
|
||||||
std::to_string(tuple_size) + " but get " +
|
std::to_string(tuple_size) + " but get " +
|
||||||
std::to_string(value_size),
|
std::to_string(value_size),
|
||||||
value_node->get_location()
|
value_node
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
} else if (tuple_size<value_size) {
|
} else if (tuple_size<value_size) {
|
||||||
|
@ -787,7 +776,7 @@ void codegen::multi_assign_gen(multi_assign* node) {
|
||||||
"too many values in multi-assignment, expect " +
|
"too many values in multi-assignment, expect " +
|
||||||
std::to_string(tuple_size) + " but get " +
|
std::to_string(tuple_size) + " but get " +
|
||||||
std::to_string(value_size),
|
std::to_string(value_size),
|
||||||
value_node->get_location()
|
value_node
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1305,13 +1294,9 @@ void codegen::block_gen(code_block* node) {
|
||||||
switch(tmp->get_type()) {
|
switch(tmp->get_type()) {
|
||||||
case expr_type::ast_use:
|
case expr_type::ast_use:
|
||||||
if (!local.empty()) {
|
if (!local.empty()) {
|
||||||
die("module import is not allowed here.",
|
die("module import is not allowed here.", tmp);
|
||||||
tmp->get_location()
|
|
||||||
);
|
|
||||||
} else if (!is_use_statement) {
|
} else if (!is_use_statement) {
|
||||||
die("module import should be used at the top of the file.",
|
die("module import should be used at top of file.", tmp);
|
||||||
tmp->get_location()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case expr_type::ast_null: break;
|
case expr_type::ast_null: break;
|
||||||
|
|
|
@ -104,8 +104,8 @@ private:
|
||||||
|
|
||||||
void check_id_exist(identifier*);
|
void check_id_exist(identifier*);
|
||||||
|
|
||||||
void die(const std::string& info, const span& loc) {
|
void die(const std::string& info, expr* node) {
|
||||||
err.err("code", loc, info);
|
err.err("code", node->get_location(), info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void regist_number(const f64);
|
void regist_number(const f64);
|
||||||
|
|
|
@ -8,16 +8,13 @@ bool symbol_finder::visit_definition_expr(definition_expr* node) {
|
||||||
// example: var a = 1;
|
// 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()
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// multiple variable definition
|
// multiple variable definition
|
||||||
// example: var (a, b, c) = (0, 1, 2);
|
// 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});
|
||||||
i->get_name(),
|
|
||||||
i->get_location()
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node->get_tuple()) {
|
if (node->get_tuple()) {
|
||||||
|
@ -37,7 +34,7 @@ bool symbol_finder::visit_iter_expr(iter_expr* node) {
|
||||||
if (node->is_definition() && node->get_name()) {
|
if (node->is_definition() && node->get_name()) {
|
||||||
symbols.push_back({
|
symbols.push_back({
|
||||||
node->get_name()->get_name(),
|
node->get_name()->get_name(),
|
||||||
node->get_name()->get_location()
|
node->get_name()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -13,7 +13,7 @@ class symbol_finder: public ast_visitor {
|
||||||
public:
|
public:
|
||||||
struct symbol_info {
|
struct symbol_info {
|
||||||
std::string name;
|
std::string name;
|
||||||
span location;
|
identifier* pos_node;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue