📝 delete nasal_misc.cpp
This commit is contained in:
parent
05605c3570
commit
4ac4675491
|
@ -39,7 +39,6 @@ set(NASAL_OBJECT_SOURCE_FILE
|
||||||
${CMAKE_SOURCE_DIR}/src/nasal_gc.cpp
|
${CMAKE_SOURCE_DIR}/src/nasal_gc.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/nasal_import.cpp
|
${CMAKE_SOURCE_DIR}/src/nasal_import.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/nasal_lexer.cpp
|
${CMAKE_SOURCE_DIR}/src/nasal_lexer.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/nasal_misc.cpp
|
|
||||||
${CMAKE_SOURCE_DIR}/src/nasal_opcode.cpp
|
${CMAKE_SOURCE_DIR}/src/nasal_opcode.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/nasal_parse.cpp
|
${CMAKE_SOURCE_DIR}/src/nasal_parse.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/nasal_type.cpp
|
${CMAKE_SOURCE_DIR}/src/nasal_type.cpp
|
||||||
|
|
15
makefile
15
makefile
|
@ -54,7 +54,6 @@ NASAL_OBJECT = \
|
||||||
build/nasal_opcode.o\
|
build/nasal_opcode.o\
|
||||||
build/symbol_finder.o\
|
build/symbol_finder.o\
|
||||||
build/nasal_codegen.o\
|
build/nasal_codegen.o\
|
||||||
build/nasal_misc.o\
|
|
||||||
build/nasal_gc.o\
|
build/nasal_gc.o\
|
||||||
build/builtin.o\
|
build/builtin.o\
|
||||||
build/fg_props.o\
|
build/fg_props.o\
|
||||||
|
@ -92,9 +91,6 @@ build:
|
||||||
build/main.o: $(NASAL_HEADER) src/main.cpp | build
|
build/main.o: $(NASAL_HEADER) src/main.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/main.cpp -o build/main.o
|
$(CXX) $(CXXFLAGS) src/main.cpp -o build/main.o
|
||||||
|
|
||||||
build/nasal_misc.o: src/nasal.h src/util/util.h src/nasal_misc.cpp | build
|
|
||||||
$(CXX) $(CXXFLAGS) src/nasal_misc.cpp -o build/nasal_misc.o
|
|
||||||
|
|
||||||
build/cli.o: src/cli/cli.h src/cli/cli.cpp | build
|
build/cli.o: src/cli/cli.h src/cli/cli.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/cli/cli.cpp -o build/cli.o
|
$(CXX) $(CXXFLAGS) src/cli/cli.cpp -o build/cli.o
|
||||||
|
|
||||||
|
@ -110,7 +106,10 @@ build/repl.o: $(NASAL_HEADER) src/repl/repl.h src/repl/repl.cpp | build
|
||||||
build/nasal_err.o: src/nasal.h src/repl/repl.h src/nasal_err.h src/nasal_err.cpp | build
|
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
|
$(CXX) $(CXXFLAGS) src/nasal_err.cpp -o build/nasal_err.o
|
||||||
|
|
||||||
build/nasal_type.o: src/nasal.h src/nasal_type.h src/nasal_type.cpp | build
|
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
|
$(CXX) $(CXXFLAGS) src/nasal_type.cpp -o build/nasal_type.o
|
||||||
|
|
||||||
build/nasal_gc.o: src/nasal.h src/nasal_type.h src/nasal_gc.h src/nasal_gc.cpp | build
|
build/nasal_gc.o: src/nasal.h src/nasal_type.h src/nasal_gc.h src/nasal_gc.cpp | build
|
||||||
|
@ -129,6 +128,7 @@ build/nasal_import.o: \
|
||||||
build/nasal_lexer.o: \
|
build/nasal_lexer.o: \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/repl/repl.h\
|
src/repl/repl.h\
|
||||||
|
src/util/util.h\
|
||||||
src/util/fs.h\
|
src/util/fs.h\
|
||||||
src/nasal_err.h\
|
src/nasal_err.h\
|
||||||
src/nasal_lexer.h src/nasal_lexer.cpp | build
|
src/nasal_lexer.h src/nasal_lexer.cpp | build
|
||||||
|
@ -163,7 +163,6 @@ build/bits_lib.o: \
|
||||||
src/natives/bits_lib.h src/natives/bits_lib.cpp | build
|
src/natives/bits_lib.h src/natives/bits_lib.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/natives/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\
|
||||||
|
@ -190,6 +189,7 @@ 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/util/util.h\
|
||||||
src/natives/json_lib.h src/natives/json_lib.cpp | build
|
src/natives/json_lib.h src/natives/json_lib.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/natives/json_lib.cpp -o build/json_lib.o
|
$(CXX) $(CXXFLAGS) src/natives/json_lib.cpp -o build/json_lib.o
|
||||||
|
|
||||||
|
@ -220,6 +220,7 @@ build/nasal_codegen.o: $(NASAL_HEADER) src/nasal_codegen.h src/nasal_codegen.cpp
|
||||||
build/nasal_opcode.o: \
|
build/nasal_opcode.o: \
|
||||||
src/nasal.h\
|
src/nasal.h\
|
||||||
src/natives/builtin.h\
|
src/natives/builtin.h\
|
||||||
|
src/util/util.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
|
||||||
|
|
||||||
|
@ -228,6 +229,7 @@ build/nasal_parse.o: \
|
||||||
src/nasal_ast.h\
|
src/nasal_ast.h\
|
||||||
src/nasal_lexer.h\
|
src/nasal_lexer.h\
|
||||||
src/nasal_err.h\
|
src/nasal_err.h\
|
||||||
|
src/util/util.h\
|
||||||
src/nasal_parse.h src/nasal_parse.cpp src/nasal_ast.h | build
|
src/nasal_parse.h src/nasal_parse.cpp src/nasal_ast.h | build
|
||||||
$(CXX) $(CXXFLAGS) src/nasal_parse.cpp -o build/nasal_parse.o
|
$(CXX) $(CXXFLAGS) src/nasal_parse.cpp -o build/nasal_parse.o
|
||||||
|
|
||||||
|
@ -259,6 +261,7 @@ build/ast_dumper.o: \
|
||||||
src/nasal_err.h\
|
src/nasal_err.h\
|
||||||
src/nasal_ast.h\
|
src/nasal_ast.h\
|
||||||
src/ast_visitor.h\
|
src/ast_visitor.h\
|
||||||
|
src/util/util.h\
|
||||||
src/ast_dumper.h src/ast_dumper.cpp | build
|
src/ast_dumper.h src/ast_dumper.cpp | build
|
||||||
$(CXX) $(CXXFLAGS) src/ast_dumper.cpp -o build/ast_dumper.o
|
$(CXX) $(CXXFLAGS) src/ast_dumper.cpp -o build/ast_dumper.o
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "ast_dumper.h"
|
#include "ast_dumper.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ bool ast_dumper::visit_number_literal(number_literal* node) {
|
||||||
|
|
||||||
bool ast_dumper::visit_string_literal(string_literal* node) {
|
bool ast_dumper::visit_string_literal(string_literal* node) {
|
||||||
dump_indent();
|
dump_indent();
|
||||||
std::cout << "string \"" << rawstr(node->get_content()) << "\"";
|
std::cout << "string \"" << util::rawstr(node->get_content()) << "\"";
|
||||||
std::cout << format_location(node);
|
std::cout << format_location(node);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
24
src/nasal.h
24
src/nasal.h
|
@ -5,11 +5,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <cstring>
|
|
||||||
#include <sstream>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
// abbreviation of some useful basic type
|
// abbreviation of some useful basic type
|
||||||
using i32 = std::int32_t;
|
using i32 = std::int32_t;
|
||||||
|
@ -21,24 +16,5 @@ using u64 = std::uint64_t;
|
||||||
using usize = std::size_t;
|
using usize = std::size_t;
|
||||||
using f64 = double;
|
using f64 = double;
|
||||||
|
|
||||||
namespace nasal {
|
|
||||||
|
|
||||||
// virtual machine stack depth, both global depth and value stack depth
|
// virtual machine stack depth, both global depth and value stack depth
|
||||||
const u32 VM_STACK_DEPTH = UINT16_MAX;
|
const u32 VM_STACK_DEPTH = UINT16_MAX;
|
||||||
|
|
||||||
f64 hex_to_f64(const char*);
|
|
||||||
f64 oct_to_f64(const char*);
|
|
||||||
// we have the same reason not using atof here
|
|
||||||
// just as andy's interpreter does.
|
|
||||||
// it is not platform independent, and may have strange output.
|
|
||||||
// so we write a new function here to convert str to number manually.
|
|
||||||
// but this also makes 0.1+0.2==0.3,
|
|
||||||
// not another result that you may get in other languages.
|
|
||||||
f64 dec_to_f64(const char*);
|
|
||||||
|
|
||||||
f64 str_to_num(const char*);
|
|
||||||
i32 utf8_hdchk(const char);
|
|
||||||
std::string char_to_hex(const char);
|
|
||||||
std::string rawstr(const std::string&, const usize maxlen = 0);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "nasal_codegen.h"
|
#include "nasal_codegen.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
||||||
|
@ -1390,7 +1391,7 @@ void codegen::print(std::ostream& out) {
|
||||||
|
|
||||||
// print const strings
|
// print const strings
|
||||||
for(const auto& str : const_string_table) {
|
for(const auto& str : const_string_table) {
|
||||||
out << " .symbol \"" << rawstr(str) << "\"\n";
|
out << " .symbol \"" << util::rawstr(str) << "\"\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// print blank line
|
// print blank line
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
#include "nasal_type.h"
|
#include "nasal_type.h"
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "nasal_lexer.h"
|
#include "nasal_lexer.h"
|
||||||
#include "repl/repl.h"
|
#include "repl/repl.h"
|
||||||
|
#include "util/util.h"
|
||||||
#include "util/fs.h"
|
#include "util/fs.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
@ -62,7 +63,7 @@ void lexer::err_char() {
|
||||||
char c = res[ptr++];
|
char c = res[ptr++];
|
||||||
err.err("lexer",
|
err.err("lexer",
|
||||||
{line, column-1, line, column, filename},
|
{line, column-1, line, column, filename},
|
||||||
"invalid character 0x" + char_to_hex(c)
|
"invalid character 0x" + util::char_to_hex(c)
|
||||||
);
|
);
|
||||||
++invalid_char;
|
++invalid_char;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +110,7 @@ std::string lexer::utf8_gen() {
|
||||||
std::string str = "";
|
std::string str = "";
|
||||||
while(ptr<res.size() && res[ptr]<0) {
|
while(ptr<res.size() && res[ptr]<0) {
|
||||||
std::string tmp = "";
|
std::string tmp = "";
|
||||||
u32 nbytes = utf8_hdchk(res[ptr]);
|
u32 nbytes = util::utf8_hdchk(res[ptr]);
|
||||||
if (!nbytes) {
|
if (!nbytes) {
|
||||||
++ptr;
|
++ptr;
|
||||||
++column;
|
++column;
|
||||||
|
@ -126,9 +127,9 @@ std::string lexer::utf8_gen() {
|
||||||
// utf8 character's total length is 1+nbytes
|
// utf8 character's total length is 1+nbytes
|
||||||
if (tmp.length()!=1+nbytes) {
|
if (tmp.length()!=1+nbytes) {
|
||||||
++column;
|
++column;
|
||||||
std::string utf_info = "0x" + char_to_hex(tmp[0]);
|
std::string utf_info = "0x" + util::char_to_hex(tmp[0]);
|
||||||
for(u32 i = 1; i<tmp.size(); ++i) {
|
for(u32 i = 1; i<tmp.size(); ++i) {
|
||||||
utf_info += " 0x" + char_to_hex(tmp[i]);
|
utf_info += " 0x" + util::char_to_hex(tmp[i]);
|
||||||
}
|
}
|
||||||
err.err("lexer",
|
err.err("lexer",
|
||||||
{line, column-1, line, column, filename},
|
{line, column-1, line, column, filename},
|
||||||
|
@ -319,7 +320,7 @@ token lexer::str_gen() {
|
||||||
++column;
|
++column;
|
||||||
|
|
||||||
// if is not utf8, 1+utf8_hdchk should be 1
|
// if is not utf8, 1+utf8_hdchk should be 1
|
||||||
if (begin=='`' && str.length()!=1+utf8_hdchk(str[0])) {
|
if (begin=='`' && str.length()!=1+util::utf8_hdchk(str[0])) {
|
||||||
err.err("lexer",
|
err.err("lexer",
|
||||||
{begin_line, begin_column, line, column, filename},
|
{begin_line, begin_column, line, column, filename},
|
||||||
"\'`\' is used for string including one character"
|
"\'`\' is used for string including one character"
|
||||||
|
|
|
@ -1,154 +0,0 @@
|
||||||
#include "nasal.h"
|
|
||||||
#include "util/util.h"
|
|
||||||
|
|
||||||
namespace nasal {
|
|
||||||
|
|
||||||
f64 hex_to_f64(const char* str) {
|
|
||||||
f64 ret = 0;
|
|
||||||
for(; *str; ++str) {
|
|
||||||
if ('0'<=*str && *str<='9') {
|
|
||||||
ret = ret*16+(*str-'0');
|
|
||||||
} else if ('a'<=*str && *str<='f') {
|
|
||||||
ret = ret*16+(*str-'a'+10);
|
|
||||||
} else if ('A'<=*str && *str<='F') {
|
|
||||||
ret = ret*16+(*str-'A'+10);
|
|
||||||
} else {
|
|
||||||
return nan("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
f64 oct_to_f64(const char* str) {
|
|
||||||
f64 ret = 0;
|
|
||||||
while('0'<=*str && *str<'8') {
|
|
||||||
ret = ret*8+(*str++-'0');
|
|
||||||
}
|
|
||||||
if (*str) {
|
|
||||||
return nan("");
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we have the same reason not using atof here
|
|
||||||
// just as andy's interpreter does.
|
|
||||||
// it is not platform independent, and may have strange output.
|
|
||||||
// so we write a new function here to convert str to number manually.
|
|
||||||
// but this also makes 0.1+0.2==0.3,
|
|
||||||
// not another result that you may get in other languages.
|
|
||||||
f64 dec_to_f64(const char* str) {
|
|
||||||
f64 ret = 0, num_pow = 0;
|
|
||||||
bool negative = false;
|
|
||||||
while('0'<=*str && *str<='9') {
|
|
||||||
ret = ret*10+(*str++-'0');
|
|
||||||
}
|
|
||||||
if (!*str) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if (*str=='.') {
|
|
||||||
if (!*++str) {
|
|
||||||
return nan("");
|
|
||||||
}
|
|
||||||
num_pow = 0.1;
|
|
||||||
while('0'<=*str && *str<='9') {
|
|
||||||
ret += num_pow*(*str++-'0');
|
|
||||||
num_pow *= 0.1;
|
|
||||||
}
|
|
||||||
if (!*str) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (*str!='e' && *str!='E') {
|
|
||||||
return nan("");
|
|
||||||
}
|
|
||||||
if (!*++str) {
|
|
||||||
return nan("");
|
|
||||||
}
|
|
||||||
if (*str=='-' || *str=='+') {
|
|
||||||
negative = (*str++=='-');
|
|
||||||
}
|
|
||||||
if (!*str) {
|
|
||||||
return nan("");
|
|
||||||
}
|
|
||||||
num_pow = 0;
|
|
||||||
while('0'<=*str && *str<='9') {
|
|
||||||
num_pow = num_pow*10+(*str++-'0');
|
|
||||||
}
|
|
||||||
if (*str) {
|
|
||||||
return nan("");
|
|
||||||
}
|
|
||||||
return negative?
|
|
||||||
ret*std::pow(10, 1-num_pow)*0.1:
|
|
||||||
ret*std::pow(10, num_pow-1)*10;
|
|
||||||
}
|
|
||||||
|
|
||||||
f64 str_to_num(const char* str) {
|
|
||||||
bool negative = false;
|
|
||||||
f64 res = 0;
|
|
||||||
if (*str=='-' || *str=='+') {
|
|
||||||
negative = (*str++=='-');
|
|
||||||
}
|
|
||||||
if (!*str) {
|
|
||||||
return nan("");
|
|
||||||
}
|
|
||||||
if (str[0]=='0' && str[1]=='x') {
|
|
||||||
res = hex_to_f64(str+2);
|
|
||||||
} else if (str[0]=='0' && str[1]=='o') {
|
|
||||||
res = oct_to_f64(str+2);
|
|
||||||
} else {
|
|
||||||
res = dec_to_f64(str);
|
|
||||||
}
|
|
||||||
return negative? -res:res;
|
|
||||||
}
|
|
||||||
|
|
||||||
i32 utf8_hdchk(const char head) {
|
|
||||||
// RFC-2279 but now we use RFC-3629 so nbytes is less than 4
|
|
||||||
const auto c = static_cast<u8>(head);
|
|
||||||
if ((c>>5)==0x06) { // 110x xxxx (10xx xxxx)^1
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if ((c>>4)==0x0e) { // 1110 xxxx (10xx xxxx)^2
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
if ((c>>3)==0x1e) { // 1111 0xxx (10xx xxxx)^3
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string char_to_hex(const char c) {
|
|
||||||
const char hextbl[] = "0123456789abcdef";
|
|
||||||
return {hextbl[(c&0xf0)>>4], hextbl[c&0x0f]};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string rawstr(const std::string& str, const usize maxlen) {
|
|
||||||
std::string ret("");
|
|
||||||
for(auto i : str) {
|
|
||||||
// windows doesn't output unicode normally, so we output the hex
|
|
||||||
if (util::is_windows() && i<=0) {
|
|
||||||
ret += "\\x" + char_to_hex(i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch(i) {
|
|
||||||
case '\0': ret += "\\0"; break;
|
|
||||||
case '\a': ret += "\\a"; break;
|
|
||||||
case '\b': ret += "\\b"; break;
|
|
||||||
case '\t': ret += "\\t"; break;
|
|
||||||
case '\n': ret += "\\n"; break;
|
|
||||||
case '\v': ret += "\\v"; break;
|
|
||||||
case '\f': ret += "\\f"; break;
|
|
||||||
case '\r': ret += "\\r"; break;
|
|
||||||
case '\033':ret += "\\e"; break;
|
|
||||||
case '\"': ret += "\\\""; break;
|
|
||||||
case '\'': ret += "\\\'"; break;
|
|
||||||
case '\\': ret += "\\\\"; break;
|
|
||||||
default: ret += i; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (maxlen && ret.length()>maxlen) {
|
|
||||||
ret = ret.substr(0, maxlen)+"...";
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "nasal_opcode.h"
|
#include "nasal_opcode.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ void codestream::dump(std::ostream& out) const {
|
||||||
break;
|
break;
|
||||||
case op_lnkeqc:
|
case op_lnkeqc:
|
||||||
out << hex << "0x" << num << dec;
|
out << hex << "0x" << num << dec;
|
||||||
out << " (" << rawstr(const_string[num], 16) << ")";
|
out << " (" << util::rawstr(const_string[num], 16) << ")";
|
||||||
break;
|
break;
|
||||||
case op_addecp:
|
case op_addecp:
|
||||||
case op_subecp:
|
case op_subecp:
|
||||||
|
@ -91,7 +92,7 @@ void codestream::dump(std::ostream& out) const {
|
||||||
break;
|
break;
|
||||||
case op_lnkecp:
|
case op_lnkecp:
|
||||||
out << hex << "0x" << num << dec;
|
out << hex << "0x" << num << dec;
|
||||||
out << " (" << rawstr(const_string[num], 16) << ") sp-1";
|
out << " (" << util::rawstr(const_string[num], 16) << ") sp-1";
|
||||||
break;
|
break;
|
||||||
case op_addc:
|
case op_addc:
|
||||||
case op_subc:
|
case op_subc:
|
||||||
|
@ -141,7 +142,7 @@ void codestream::dump(std::ostream& out) const {
|
||||||
case op_deft:
|
case op_deft:
|
||||||
case op_dyn:
|
case op_dyn:
|
||||||
out << hex << "0x" << num << dec;
|
out << hex << "0x" << num << dec;
|
||||||
out << " (" << rawstr(const_string[num], 16) << ")";
|
out << " (" << util::rawstr(const_string[num], 16) << ")";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (files) {
|
if (files) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "nasal_ast.h"
|
#include "nasal_ast.h"
|
||||||
#include "nasal_parse.h"
|
#include "nasal_parse.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
||||||
|
@ -227,8 +228,10 @@ nil_expr* parse::nil() {
|
||||||
}
|
}
|
||||||
|
|
||||||
number_literal* parse::num() {
|
number_literal* parse::num() {
|
||||||
auto node = new number_literal(toks[ptr].loc,
|
auto node = new number_literal(
|
||||||
str_to_num(toks[ptr].str.c_str()));
|
toks[ptr].loc,
|
||||||
|
util::str_to_num(toks[ptr].str.c_str())
|
||||||
|
);
|
||||||
match(tok::tk_num);
|
match(tok::tk_num);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "nasal_type.h"
|
#include "nasal_type.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -268,7 +269,7 @@ void nas_val::clear() {
|
||||||
}
|
}
|
||||||
|
|
||||||
f64 var::to_num() {
|
f64 var::to_num() {
|
||||||
return type!=vm_type::vm_str? val.num:str_to_num(str().c_str());
|
return type!=vm_type::vm_str? val.num:util::str_to_num(str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string var::to_str() {
|
std::string var::to_str() {
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "nasal_vm.h"
|
#include "nasal_vm.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@ void vm::value_info(var& val) {
|
||||||
case vm_type::vm_nil: std::clog << "| nil |"; break;
|
case vm_type::vm_nil: std::clog << "| nil |"; break;
|
||||||
case vm_type::vm_num: std::clog << "| num | " << val.num(); break;
|
case vm_type::vm_num: std::clog << "| num | " << val.num(); break;
|
||||||
case vm_type::vm_str: std::clog << "| str | <0x" << std::hex << p
|
case vm_type::vm_str: std::clog << "| str | <0x" << std::hex << p
|
||||||
<< "> \"" << rawstr(val.str(), 16)
|
<< "> \"" << util::rawstr(val.str(), 16)
|
||||||
<< "\"" << std::dec; break;
|
<< "\"" << std::dec; break;
|
||||||
case vm_type::vm_func: std::clog << "| func | <0x" << std::hex << p
|
case vm_type::vm_func: std::clog << "| func | <0x" << std::hex << p
|
||||||
<< std::dec << "> " << val.func();
|
<< std::dec << "> " << val.func();
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "nasal_import.h"
|
#include "nasal_import.h"
|
||||||
#include "nasal_gc.h"
|
#include "nasal_gc.h"
|
||||||
#include "nasal_codegen.h"
|
#include "nasal_codegen.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning (disable:4244)
|
#pragma warning (disable:4244)
|
||||||
|
@ -216,7 +217,7 @@ inline bool vm::cond(var& val) {
|
||||||
if (val.is_num()) {
|
if (val.is_num()) {
|
||||||
return val.num();
|
return val.num();
|
||||||
} else if (val.is_str()) {
|
} else if (val.is_str()) {
|
||||||
const f64 num = str_to_num(val.str().c_str());
|
const f64 num = util::str_to_num(val.str().c_str());
|
||||||
return std::isnan(num)? !val.str().empty():num;
|
return std::isnan(num)? !val.str().empty():num;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -333,7 +334,7 @@ inline void vm::o_lnot() {
|
||||||
case vm_type::vm_nil: ctx.top[0] = one; break;
|
case vm_type::vm_nil: ctx.top[0] = one; break;
|
||||||
case vm_type::vm_num: ctx.top[0] = val.num()? zero:one; break;
|
case vm_type::vm_num: ctx.top[0] = val.num()? zero:one; break;
|
||||||
case vm_type::vm_str: {
|
case vm_type::vm_str: {
|
||||||
const f64 num = str_to_num(val.str().c_str());
|
const f64 num = util::str_to_num(val.str().c_str());
|
||||||
if (std::isnan(num)) {
|
if (std::isnan(num)) {
|
||||||
ctx.top[0] = var::num(static_cast<f64>(val.str().empty()));
|
ctx.top[0] = var::num(static_cast<f64>(val.str().empty()));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "natives/io_lib.h"
|
#include "natives/io_lib.h"
|
||||||
#include "util/fs.h"
|
#include "util/fs.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "natives/json_lib.h"
|
#include "natives/json_lib.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -170,7 +171,7 @@ void json::next() {
|
||||||
} else if (text[ptr]!=' ' && text[ptr]!='\t' && text[ptr]!='\r') {
|
} else if (text[ptr]!=' ' && text[ptr]!='\t' && text[ptr]!='\r') {
|
||||||
error_info() += "json::parse: line " + std::to_string(line);
|
error_info() += "json::parse: line " + std::to_string(line);
|
||||||
error_info() += ": invalid character `0x";
|
error_info() += ": invalid character `0x";
|
||||||
error_info() += char_to_hex(text[ptr]);
|
error_info() += util::char_to_hex(text[ptr]);
|
||||||
error_info() += "`\n";
|
error_info() += "`\n";
|
||||||
}
|
}
|
||||||
++ptr;
|
++ptr;
|
||||||
|
@ -253,7 +254,7 @@ void json::vector_member(nas_vec& vec, gc* ngc) {
|
||||||
vec.elems.push_back(ngc->newstr(this_token.content));
|
vec.elems.push_back(ngc->newstr(this_token.content));
|
||||||
next();
|
next();
|
||||||
} else if (this_token.type==json_token_type::tok_num) {
|
} else if (this_token.type==json_token_type::tok_num) {
|
||||||
vec.elems.push_back(var::num(str_to_num(this_token.content.c_str())));
|
vec.elems.push_back(var::num(util::str_to_num(this_token.content.c_str())));
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,7 +293,7 @@ void json::hash_member(nas_hash& hash, gc* ngc) {
|
||||||
hash.elems.insert({name, ngc->newstr(this_token.content)});
|
hash.elems.insert({name, ngc->newstr(this_token.content)});
|
||||||
next();
|
next();
|
||||||
} else if (this_token.type==json_token_type::tok_num) {
|
} else if (this_token.type==json_token_type::tok_num) {
|
||||||
hash.elems.insert({name, var::num(str_to_num(this_token.content.c_str()))});
|
hash.elems.insert({name, var::num(util::str_to_num(this_token.content.c_str()))});
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
namespace nasal::util {
|
namespace nasal::util {
|
||||||
|
|
||||||
bool is_windows() {
|
bool is_windows() {
|
||||||
|
@ -118,4 +120,152 @@ const char* get_arch() {
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 utf8_hdchk(const char head) {
|
||||||
|
// RFC-2279 but now we use RFC-3629 so nbytes is less than 4
|
||||||
|
const auto c = static_cast<u8>(head);
|
||||||
|
if ((c>>5)==0x06) { // 110x xxxx (10xx xxxx)^1
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ((c>>4)==0x0e) { // 1110 xxxx (10xx xxxx)^2
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if ((c>>3)==0x1e) { // 1111 0xxx (10xx xxxx)^3
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string char_to_hex(const char c) {
|
||||||
|
const char hextbl[] = "0123456789abcdef";
|
||||||
|
return {hextbl[(c&0xf0)>>4], hextbl[c&0x0f]};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string rawstr(const std::string& str, const usize maxlen) {
|
||||||
|
std::string ret("");
|
||||||
|
for(auto i : str) {
|
||||||
|
// windows doesn't output unicode normally, so we output the hex
|
||||||
|
if (util::is_windows() && i<=0) {
|
||||||
|
ret += "\\x" + char_to_hex(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch(i) {
|
||||||
|
case '\0': ret += "\\0"; break;
|
||||||
|
case '\a': ret += "\\a"; break;
|
||||||
|
case '\b': ret += "\\b"; break;
|
||||||
|
case '\t': ret += "\\t"; break;
|
||||||
|
case '\n': ret += "\\n"; break;
|
||||||
|
case '\v': ret += "\\v"; break;
|
||||||
|
case '\f': ret += "\\f"; break;
|
||||||
|
case '\r': ret += "\\r"; break;
|
||||||
|
case '\033':ret += "\\e"; break;
|
||||||
|
case '\"': ret += "\\\""; break;
|
||||||
|
case '\'': ret += "\\\'"; break;
|
||||||
|
case '\\': ret += "\\\\"; break;
|
||||||
|
default: ret += i; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxlen && ret.length()>maxlen) {
|
||||||
|
ret = ret.substr(0, maxlen)+"...";
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
f64 hex_to_f64(const char* str) {
|
||||||
|
f64 ret = 0;
|
||||||
|
for(; *str; ++str) {
|
||||||
|
if ('0'<=*str && *str<='9') {
|
||||||
|
ret = ret*16+(*str-'0');
|
||||||
|
} else if ('a'<=*str && *str<='f') {
|
||||||
|
ret = ret*16+(*str-'a'+10);
|
||||||
|
} else if ('A'<=*str && *str<='F') {
|
||||||
|
ret = ret*16+(*str-'A'+10);
|
||||||
|
} else {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
f64 oct_to_f64(const char* str) {
|
||||||
|
f64 ret = 0;
|
||||||
|
while('0'<=*str && *str<'8') {
|
||||||
|
ret = ret*8+(*str++-'0');
|
||||||
|
}
|
||||||
|
if (*str) {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we have the same reason not using atof here
|
||||||
|
// just as andy's interpreter does.
|
||||||
|
// it is not platform independent, and may have strange output.
|
||||||
|
// so we write a new function here to convert str to number manually.
|
||||||
|
// but this also makes 0.1+0.2==0.3,
|
||||||
|
// not another result that you may get in other languages.
|
||||||
|
f64 dec_to_f64(const char* str) {
|
||||||
|
f64 ret = 0, num_pow = 0;
|
||||||
|
bool negative = false;
|
||||||
|
while('0'<=*str && *str<='9') {
|
||||||
|
ret = ret*10+(*str++-'0');
|
||||||
|
}
|
||||||
|
if (!*str) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (*str=='.') {
|
||||||
|
if (!*++str) {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
num_pow = 0.1;
|
||||||
|
while('0'<=*str && *str<='9') {
|
||||||
|
ret += num_pow*(*str++-'0');
|
||||||
|
num_pow *= 0.1;
|
||||||
|
}
|
||||||
|
if (!*str) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*str!='e' && *str!='E') {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
if (!*++str) {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
if (*str=='-' || *str=='+') {
|
||||||
|
negative = (*str++=='-');
|
||||||
|
}
|
||||||
|
if (!*str) {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
num_pow = 0;
|
||||||
|
while('0'<=*str && *str<='9') {
|
||||||
|
num_pow = num_pow*10+(*str++-'0');
|
||||||
|
}
|
||||||
|
if (*str) {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
return negative?
|
||||||
|
ret*std::pow(10, 1-num_pow)*0.1:
|
||||||
|
ret*std::pow(10, num_pow-1)*10;
|
||||||
|
}
|
||||||
|
|
||||||
|
f64 str_to_num(const char* str) {
|
||||||
|
bool negative = false;
|
||||||
|
f64 res = 0;
|
||||||
|
if (*str=='-' || *str=='+') {
|
||||||
|
negative = (*str++=='-');
|
||||||
|
}
|
||||||
|
if (!*str) {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
if (str[0]=='0' && str[1]=='x') {
|
||||||
|
res = hex_to_f64(str+2);
|
||||||
|
} else if (str[0]=='0' && str[1]=='o') {
|
||||||
|
res = oct_to_f64(str+2);
|
||||||
|
} else {
|
||||||
|
res = dec_to_f64(str);
|
||||||
|
}
|
||||||
|
return negative? -res:res;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,4 +1,9 @@
|
||||||
#pragma
|
#pragma once
|
||||||
|
|
||||||
|
#include "nasal.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace nasal::util {
|
namespace nasal::util {
|
||||||
|
|
||||||
|
@ -16,4 +21,21 @@ bool is_superh();
|
||||||
const char* get_platform();
|
const char* get_platform();
|
||||||
const char* get_arch();
|
const char* get_arch();
|
||||||
|
|
||||||
|
u32 utf8_hdchk(const char);
|
||||||
|
|
||||||
|
std::string char_to_hex(const char);
|
||||||
|
std::string rawstr(const std::string&, const usize maxlen = 0);
|
||||||
|
|
||||||
|
f64 hex_to_f64(const char*);
|
||||||
|
f64 oct_to_f64(const char*);
|
||||||
|
// we have the same reason not using atof here
|
||||||
|
// just as andy's interpreter does.
|
||||||
|
// it is not platform independent, and may have strange output.
|
||||||
|
// so we write a new function here to convert str to number manually.
|
||||||
|
// but this also makes 0.1+0.2==0.3,
|
||||||
|
// not another result that you may get in other languages.
|
||||||
|
f64 dec_to_f64(const char*);
|
||||||
|
|
||||||
|
f64 str_to_num(const char*);
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue