diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b18d87..dae8956 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ set(NASAL_OBJECT_SOURCE_FILE ${CMAKE_SOURCE_DIR}/src/nasal_ast.cpp ${CMAKE_SOURCE_DIR}/src/nasal_builtin.cpp ${CMAKE_SOURCE_DIR}/src/fg_props.cpp + ${CMAKE_SOURCE_DIR}/src/math_lib.cpp ${CMAKE_SOURCE_DIR}/src/nasal_codegen.cpp ${CMAKE_SOURCE_DIR}/src/nasal_dbg.cpp ${CMAKE_SOURCE_DIR}/src/nasal_err.cpp diff --git a/makefile b/makefile index 7db2e34..636cd5f 100644 --- a/makefile +++ b/makefile @@ -17,7 +17,8 @@ NASAL_HEADER=\ src/nasal.h\ src/optimizer.h\ src/symbol_finder.h\ - src/fg_props.h + src/fg_props.h\ + src/math_lib.h NASAL_OBJECT=\ build/nasal_err.o\ @@ -35,6 +36,7 @@ NASAL_OBJECT=\ build/nasal_gc.o\ build/nasal_builtin.o\ build/fg_props.o\ + build/math_lib.o\ build/nasal_vm.o\ build/nasal_dbg.o\ build/main.o @@ -87,6 +89,12 @@ build/nasal_builtin.o: \ src/nasal_builtin.h src/nasal_builtin.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_builtin.cpp -fno-exceptions -fPIC -o build/nasal_builtin.o -I . +build/math_lib.o: \ + src/nasal.h\ + src/nasal_gc.h\ + src/math_lib.h src/math_lib.cpp | build + $(CXX) -std=$(STD) -c -O3 src/math_lib.cpp -fno-exceptions -fPIC -o build/math_lib.o -I . + build/fg_props.o: \ src/nasal.h\ src/nasal_gc.h\ diff --git a/src/math_lib.cpp b/src/math_lib.cpp new file mode 100644 index 0000000..ecda7cc --- /dev/null +++ b/src/math_lib.cpp @@ -0,0 +1,73 @@ +#include "math_lib.h" + +var builtin_pow(var* local, gc& ngc) { + var x = local[1]; + var y = local[2]; + if (x.type!=vm_num || y.type!=vm_num) { + return var::num(std::nan("")); + } + return var::num(std::pow(x.num(), y.num())); +} + +var builtin_sin(var* local, gc& ngc) { + var val = local[1]; + return var::num(val.type==vm_num?sin(val.num()):std::nan("")); +} + +var builtin_cos(var* local, gc& ngc) { + var val = local[1]; + return var::num(val.type==vm_num?cos(val.num()):std::nan("")); +} + +var builtin_tan(var* local, gc& ngc) { + var val = local[1]; + return var::num(val.type==vm_num?tan(val.num()):std::nan("")); +} + +var builtin_exp(var* local, gc& ngc) { + var val = local[1]; + return var::num(val.type==vm_num?exp(val.num()):std::nan("")); +} + +var builtin_lg(var* local, gc& ngc) { + var val = local[1]; + return var::num(val.type==vm_num?log(val.num())/log(10.0):std::nan("")); +} + +var builtin_ln(var* local, gc& ngc) { + var val = local[1]; + return var::num(val.type==vm_num?log(val.num()):std::nan("")); +} + +var builtin_sqrt(var* local, gc& ngc) { + var val = local[1]; + return var::num(val.type==vm_num?sqrt(val.num()):std::nan("")); +} + +var builtin_atan2(var* local, gc& ngc) { + var x = local[1]; + var y = local[2]; + if (x.type!=vm_num || y.type!=vm_num) { + return var::num(std::nan("")); + } + return var::num(atan2(y.num(), x.num())); +} + +var builtin_isnan(var* local, gc& ngc) { + var x = local[1]; + return (x.type==vm_num && std::isnan(x.num()))?one:zero; +} + +nasal_builtin_table math_lib_native[] = { + {"__pow", builtin_pow}, + {"__sin", builtin_sin}, + {"__cos", builtin_cos}, + {"__tan", builtin_tan}, + {"__exp", builtin_exp}, + {"__lg", builtin_lg}, + {"__ln", builtin_ln}, + {"__sqrt", builtin_sqrt}, + {"__atan2", builtin_atan2}, + {"__isnan", builtin_isnan}, + {nullptr, nullptr} +}; \ No newline at end of file diff --git a/src/math_lib.h b/src/math_lib.h new file mode 100644 index 0000000..2b9e1a4 --- /dev/null +++ b/src/math_lib.h @@ -0,0 +1,18 @@ +#pragma once + +#include "nasal.h" +#include "nasal_gc.h" +#include "nasal_builtin.h" + +var builtin_pow(var*, gc&); +var builtin_sin(var*, gc&); +var builtin_cos(var*, gc&); +var builtin_tan(var*, gc&); +var builtin_exp(var*, gc&); +var builtin_lg(var*, gc&); +var builtin_ln(var*, gc&); +var builtin_sqrt(var*, gc&); +var builtin_atan2(var*, gc&); +var builtin_isnan(var*, gc&); + +extern nasal_builtin_table math_lib_native[]; \ No newline at end of file diff --git a/src/nasal_builtin.cpp b/src/nasal_builtin.cpp index 4ceed8e..bf9b4a5 100644 --- a/src/nasal_builtin.cpp +++ b/src/nasal_builtin.cpp @@ -243,64 +243,6 @@ var builtin_u32not(var* local, gc& ngc) { return var::num((f64)(u32)(~u32(local[1].num()))); } -var builtin_pow(var* local, gc& ngc) { - var x = local[1]; - var y = local[2]; - if (x.type!=vm_num || y.type!=vm_num) { - return var::num(std::nan("")); - } - return var::num(std::pow(x.num(), y.num())); -} - -var builtin_sin(var* local, gc& ngc) { - var val = local[1]; - return var::num(val.type==vm_num?sin(val.num()):std::nan("")); -} - -var builtin_cos(var* local, gc& ngc) { - var val = local[1]; - return var::num(val.type==vm_num?cos(val.num()):std::nan("")); -} - -var builtin_tan(var* local, gc& ngc) { - var val = local[1]; - return var::num(val.type==vm_num?tan(val.num()):std::nan("")); -} - -var builtin_exp(var* local, gc& ngc) { - var val = local[1]; - return var::num(val.type==vm_num?exp(val.num()):std::nan("")); -} - -var builtin_lg(var* local, gc& ngc) { - var val = local[1]; - return var::num(val.type==vm_num?log(val.num())/log(10.0):std::nan("")); -} - -var builtin_ln(var* local, gc& ngc) { - var val = local[1]; - return var::num(val.type==vm_num?log(val.num()):std::nan("")); -} - -var builtin_sqrt(var* local, gc& ngc) { - var val = local[1]; - return var::num(val.type==vm_num?sqrt(val.num()):std::nan("")); -} - -var builtin_atan2(var* local, gc& ngc) { - var x = local[1]; - var y = local[2]; - if (x.type!=vm_num || y.type!=vm_num) { - return var::num(std::nan("")); - } - return var::num(atan2(y.num(), x.num())); -} - -var builtin_isnan(var* local, gc& ngc) { - var x = local[1]; - return (x.type==vm_num && std::isnan(x.num()))?one:zero; -} - var builtin_time(var* local, gc& ngc) { var val = local[1]; if (val.type!=vm_num) { @@ -1306,16 +1248,6 @@ nasal_builtin_table builtin[] = { {"__u32or", builtin_u32or}, {"__u32nand", builtin_u32nand}, {"__u32not", builtin_u32not}, - {"__pow", builtin_pow}, - {"__sin", builtin_sin}, - {"__cos", builtin_cos}, - {"__tan", builtin_tan}, - {"__exp", builtin_exp}, - {"__lg", builtin_lg}, - {"__ln", builtin_ln}, - {"__sqrt", builtin_sqrt}, - {"__atan2", builtin_atan2}, - {"__isnan", builtin_isnan}, {"__time", builtin_time}, {"__contains", builtin_contains}, {"__delete", builtin_delete}, diff --git a/src/nasal_builtin.h b/src/nasal_builtin.h index d14d62d..85a8050 100644 --- a/src/nasal_builtin.h +++ b/src/nasal_builtin.h @@ -59,16 +59,6 @@ var builtin_u32and(var*, gc&); var builtin_u32or(var*, gc&); var builtin_u32nand(var*, gc&); var builtin_u32not(var*, gc&); -var builtin_pow(var*, gc&); -var builtin_sin(var*, gc&); -var builtin_cos(var*, gc&); -var builtin_tan(var*, gc&); -var builtin_exp(var*, gc&); -var builtin_lg(var*, gc&); -var builtin_ln(var*, gc&); -var builtin_sqrt(var*, gc&); -var builtin_atan2(var*, gc&); -var builtin_isnan(var*, gc&); var builtin_time(var*, gc&); var builtin_contains(var*, gc&); var builtin_delete(var*, gc&); diff --git a/src/nasal_codegen.cpp b/src/nasal_codegen.cpp index b3b7753..6d16310 100644 --- a/src/nasal_codegen.cpp +++ b/src/nasal_codegen.cpp @@ -14,6 +14,7 @@ void codegen::load_native_function_table(nasal_builtin_table* table) { void codegen::init_native_function() { load_native_function_table(builtin); + load_native_function_table(math_lib_native); load_native_function_table(flight_gear_native); } diff --git a/src/nasal_codegen.h b/src/nasal_codegen.h index 2e8ca94..fbfe11b 100644 --- a/src/nasal_codegen.h +++ b/src/nasal_codegen.h @@ -9,6 +9,7 @@ #include "nasal_import.h" #include "nasal_builtin.h" +#include "math_lib.h" #include "fg_props.h" #include diff --git a/std/math.nas b/std/math.nas index b3c7e1d..a19ea80 100644 --- a/std/math.nas +++ b/std/math.nas @@ -2,16 +2,29 @@ # 2023 by ValKmjolnir # mostly used math functions and special constants, you know. +# constant e var e = 2.7182818284590452354; + +# constant pi var pi = 3.14159265358979323846264338327950288; +# maybe useless, just tell you +# how to make inf and nan in IEEE754 double. +# carefully using these two constants, +# may cause critical error in calculation. var inf = 1/0; + +# nan can be created by (inf - inf) or (-inf + inf) var nan = 0/0; var abs = func(x) { return x>0? x:-x; } +# floor will get the integral number of input argument +# which is less than or equal to this argument. +# this is basic native function in old nasal, +# but we think it should have a copy in math module. var floor = func(x) { return __floor(x); }