diff --git a/CMakeLists.txt b/CMakeLists.txt index b86c9bf..8dbdfd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,7 @@ set(NASAL_OBJECT_SOURCE_FILE ${CMAKE_SOURCE_DIR}/src/nasal_builtin.cpp ${CMAKE_SOURCE_DIR}/src/coroutine.cpp ${CMAKE_SOURCE_DIR}/src/fg_props.cpp + ${CMAKE_SOURCE_DIR}/src/bits_lib.cpp ${CMAKE_SOURCE_DIR}/src/math_lib.cpp ${CMAKE_SOURCE_DIR}/src/nasal_codegen.cpp ${CMAKE_SOURCE_DIR}/src/nasal_dbg.cpp diff --git a/makefile b/makefile index 713cd42..0276c49 100644 --- a/makefile +++ b/makefile @@ -18,6 +18,7 @@ NASAL_HEADER=\ src/optimizer.h\ src/symbol_finder.h\ src/fg_props.h\ + src/bits_lib.h\ src/math_lib.h\ src/coroutine.h @@ -25,6 +26,7 @@ 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\ @@ -97,6 +99,12 @@ build/coroutine.o: \ src/coroutine.h src/coroutine.cpp | build $(CXX) -std=$(STD) -c -O3 src/coroutine.cpp -fno-exceptions -fPIC -o build/coroutine.o -I . +build/bits_lib.o: \ + src/nasal.h\ + src/nasal_gc.h\ + src/bits_lib.h src/bits_lib.cpp | build + $(CXX) -std=$(STD) -c -O3 src/bits_lib.cpp -fno-exceptions -fPIC -o build/bits_lib.o -I . + build/math_lib.o: \ src/nasal.h\ src/nasal_gc.h\ diff --git a/src/bits_lib.cpp b/src/bits_lib.cpp new file mode 100644 index 0000000..67cdf1d --- /dev/null +++ b/src/bits_lib.cpp @@ -0,0 +1,137 @@ +#include "bits_lib.h" + +var builtin_u32xor(var* local, gc& ngc) { + return var::num((f64)(u32(local[1].num())^u32(local[2].num()))); +} + +var builtin_u32and(var* local, gc& ngc) { + return var::num((f64)(u32(local[1].num())&u32(local[2].num()))); +} + +var builtin_u32or(var* local, gc& ngc) { + return var::num((f64)(u32(local[1].num())|u32(local[2].num()))); +} + +var builtin_u32nand(var* local, gc& ngc) { + return var::num((f64)(u32)(~(u32(local[1].num())&u32(local[2].num())))); +} + +var builtin_u32not(var* local, gc& ngc) { + return var::num((f64)(u32)(~u32(local[1].num()))); +} + +var builtin_fld(var* local, gc& ngc) { + // bits.fld(s,0,3); + // if s stores 10100010(162) + // will get 101(5) + var str = local[1]; + var startbit = local[2]; + var length = local[3]; + if (str.type!=vm_str || str.val.gcobj->unmut) { + return nas_err("fld", "\"str\" must be mutable string"); + } + if (startbit.type!=vm_num || length.type!=vm_num) { + return nas_err("fld", "\"startbit\",\"len\" must be number"); + } + u32 bit = (u32)startbit.num(); + u32 len = (u32)length.num(); + if (bit+len>8*str.str().length()) { + return nas_err("fld", "bitfield out of bounds"); + } + u32 res = 0; + auto& s = str.str(); + for(u32 i = bit; i>3]&(1<<(7-(i&7)))) { + res |= 1<<(bit+len-i-1); + } + } + return var::num((f64)res); +} + +var builtin_sfld(var* local, gc& ngc) { + // bits.sfld(s,0,3); + // if s stores 10100010(162) + // will get 101(5) then this will be signed extended to + // 11111101(-3) + var str = local[1]; + var startbit = local[2]; + var length = local[3]; + if (str.type!=vm_str || str.val.gcobj->unmut) { + return nas_err("sfld", "\"str\" must be mutable string"); + } + if (startbit.type!=vm_num || length.type!=vm_num) { + return nas_err("sfld", "\"startbit\",\"len\" must be number"); + } + u32 bit = (u32)startbit.num(); + u32 len = (u32)length.num(); + if (bit+len>8*str.str().length()) { + return nas_err("sfld", "bitfield out of bounds"); + } + u32 res = 0; + auto& s = str.str(); + for(u32 i = bit; i>3]&(1<<(7-(i&7)))) { + res |= 1<<(bit+len-i-1); + } + } + if (res&(1<<(len-1))) { + res |= ~((1<unmut) { + return nas_err("setfld", "\"str\" must be mutable string"); + } + if (startbit.type!=vm_num || length.type!=vm_num || value.type!=vm_num) { + return nas_err("setfld", "\"startbit\",\"len\",\"val\" must be number"); + } + u32 bit = (u32)startbit.num(); + u32 len = (u32)length.num(); + u64 val = (u64)value.num(); + if (bit+len>8*str.str().length()) { + return nas_err("setfld", "bitfield out of bounds"); + } + auto& s = str.str(); + for(u32 i = bit; i>3] |= (1<<(7-(i&7))); + } else { + s[i>>3] &= ~(1<<(7-(i&7))); + } + } + return nil; +} + +var builtin_buf(var* local, gc& ngc) { + var length = local[1]; + if (length.type!=vm_num || length.num()<=0) { + return nas_err("buf", "\"len\" must be number greater than 0"); + } + var str = ngc.alloc(vm_str); + auto& s = str.str(); + s.resize(length.num(), '\0'); + return str; +} + +nasal_builtin_table bits_native[] = { + {"__u32xor", builtin_u32xor}, + {"__u32and", builtin_u32and}, + {"__u32or", builtin_u32or}, + {"__u32nand", builtin_u32nand}, + {"__u32not", builtin_u32not}, + {"__fld", builtin_fld}, + {"__sfld", builtin_sfld}, + {"__setfld", builtin_setfld}, + {"__buf", builtin_buf}, + {nullptr, nullptr} +}; \ No newline at end of file diff --git a/src/bits_lib.h b/src/bits_lib.h new file mode 100644 index 0000000..72fbca9 --- /dev/null +++ b/src/bits_lib.h @@ -0,0 +1,17 @@ +#pragma once + +#include "nasal.h" +#include "nasal_gc.h" +#include "nasal_builtin.h" + +var builtin_u32xor(var*, gc&); +var builtin_u32and(var*, gc&); +var builtin_u32or(var*, gc&); +var builtin_u32nand(var*, gc&); +var builtin_u32not(var*, gc&); +var builtin_fld(var*, gc&); +var builtin_sfld(var*, gc&); +var builtin_setfld(var*, gc&); +var builtin_buf(var*, gc&); + +extern nasal_builtin_table bits_native[]; diff --git a/src/nasal_builtin.cpp b/src/nasal_builtin.cpp index c42f94d..60ec19e 100644 --- a/src/nasal_builtin.cpp +++ b/src/nasal_builtin.cpp @@ -223,26 +223,6 @@ var builtin_size(var* local, gc& ngc) { return var::num(num); } -var builtin_u32xor(var* local, gc& ngc) { - return var::num((f64)(u32(local[1].num())^u32(local[2].num()))); -} - -var builtin_u32and(var* local, gc& ngc) { - return var::num((f64)(u32(local[1].num())&u32(local[2].num()))); -} - -var builtin_u32or(var* local, gc& ngc) { - return var::num((f64)(u32(local[1].num())|u32(local[2].num()))); -} - -var builtin_u32nand(var* local, gc& ngc) { - return var::num((f64)(u32)(~(u32(local[1].num())&u32(local[2].num())))); -} - -var builtin_u32not(var* local, gc& ngc) { - return var::num((f64)(u32)(~u32(local[1].num()))); -} - var builtin_time(var* local, gc& ngc) { var val = local[1]; if (val.type!=vm_num) { @@ -590,109 +570,6 @@ var builtin_eof(var* local, gc& ngc) { return var::num((f64)feof((FILE*)fd.obj().ptr)); } -var builtin_fld(var* local, gc& ngc) { - // bits.fld(s,0,3); - // if s stores 10100010(162) - // will get 101(5) - var str = local[1]; - var startbit = local[2]; - var length = local[3]; - if (str.type!=vm_str || str.val.gcobj->unmut) { - return nas_err("fld", "\"str\" must be mutable string"); - } - if (startbit.type!=vm_num || length.type!=vm_num) { - return nas_err("fld", "\"startbit\",\"len\" must be number"); - } - u32 bit = (u32)startbit.num(); - u32 len = (u32)length.num(); - if (bit+len>8*str.str().length()) { - return nas_err("fld", "bitfield out of bounds"); - } - u32 res = 0; - auto& s = str.str(); - for(u32 i = bit; i>3]&(1<<(7-(i&7)))) { - res |= 1<<(bit+len-i-1); - } - } - return var::num((f64)res); -} - -var builtin_sfld(var* local, gc& ngc) { - // bits.sfld(s,0,3); - // if s stores 10100010(162) - // will get 101(5) then this will be signed extended to - // 11111101(-3) - var str = local[1]; - var startbit = local[2]; - var length = local[3]; - if (str.type!=vm_str || str.val.gcobj->unmut) { - return nas_err("sfld", "\"str\" must be mutable string"); - } - if (startbit.type!=vm_num || length.type!=vm_num) { - return nas_err("sfld", "\"startbit\",\"len\" must be number"); - } - u32 bit = (u32)startbit.num(); - u32 len = (u32)length.num(); - if (bit+len>8*str.str().length()) { - return nas_err("sfld", "bitfield out of bounds"); - } - u32 res = 0; - auto& s = str.str(); - for(u32 i = bit; i>3]&(1<<(7-(i&7)))) { - res |= 1<<(bit+len-i-1); - } - } - if (res&(1<<(len-1))) { - res |= ~((1<unmut) { - return nas_err("setfld", "\"str\" must be mutable string"); - } - if (startbit.type!=vm_num || length.type!=vm_num || value.type!=vm_num) { - return nas_err("setfld", "\"startbit\",\"len\",\"val\" must be number"); - } - u32 bit = (u32)startbit.num(); - u32 len = (u32)length.num(); - u64 val = (u64)value.num(); - if (bit+len>8*str.str().length()) { - return nas_err("setfld", "bitfield out of bounds"); - } - auto& s = str.str(); - for(u32 i = bit; i>3] |= (1<<(7-(i&7))); - } else { - s[i>>3] &= ~(1<<(7-(i&7))); - } - } - return nil; -} - -var builtin_buf(var* local, gc& ngc) { - var length = local[1]; - if (length.type!=vm_num || length.num()<=0) { - return nas_err("buf", "\"len\" must be number greater than 0"); - } - var str = ngc.alloc(vm_str); - auto& s = str.str(); - s.resize(length.num(), '\0'); - return str; -} - var builtin_sleep(var* local, gc& ngc) { var val = local[1]; if (val.type!=vm_num) { @@ -1137,11 +1014,6 @@ nasal_builtin_table builtin[] = { {"__pop", builtin_pop}, {"__str", builtin_str}, {"__size", builtin_size}, - {"__u32xor", builtin_u32xor}, - {"__u32and", builtin_u32and}, - {"__u32or", builtin_u32or}, - {"__u32nand", builtin_u32nand}, - {"__u32not", builtin_u32not}, {"__time", builtin_time}, {"__contains", builtin_contains}, {"__delete", builtin_delete}, @@ -1167,10 +1039,6 @@ nasal_builtin_table builtin[] = { {"__readln", builtin_readln}, {"__stat", builtin_stat}, {"__eof", builtin_eof}, - {"__fld", builtin_fld}, - {"__sfld", builtin_sfld}, - {"__setfld", builtin_setfld}, - {"__buf", builtin_buf}, {"__sleep", builtin_sleep}, {"__pipe", builtin_pipe}, {"__fork", builtin_fork}, diff --git a/src/nasal_builtin.h b/src/nasal_builtin.h index 5c62658..f4a4e3d 100644 --- a/src/nasal_builtin.h +++ b/src/nasal_builtin.h @@ -54,11 +54,6 @@ var builtin_num(var*, gc&); var builtin_pop(var*, gc&); var builtin_str(var*, gc&); var builtin_size(var*, gc&); -var builtin_u32xor(var*, gc&); -var builtin_u32and(var*, gc&); -var builtin_u32or(var*, gc&); -var builtin_u32nand(var*, gc&); -var builtin_u32not(var*, gc&); var builtin_time(var*, gc&); var builtin_contains(var*, gc&); var builtin_delete(var*, gc&); @@ -84,10 +79,6 @@ var builtin_tell(var*, gc&); var builtin_readln(var*, gc&); var builtin_stat(var*, gc&); var builtin_eof(var*, gc&); -var builtin_fld(var*, gc&); -var builtin_sfld(var*, gc&); -var builtin_setfld(var*, gc&); -var builtin_buf(var*, gc&); var builtin_sleep(var*, gc&); var builtin_pipe(var*, gc&); var builtin_fork(var*, gc&); diff --git a/src/nasal_codegen.cpp b/src/nasal_codegen.cpp index 3101188..88b49d2 100644 --- a/src/nasal_codegen.cpp +++ b/src/nasal_codegen.cpp @@ -15,6 +15,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(bits_native); load_native_function_table(coroutine_native); load_native_function_table(flight_gear_native); } diff --git a/src/nasal_codegen.h b/src/nasal_codegen.h index 3913790..da81f01 100644 --- a/src/nasal_codegen.h +++ b/src/nasal_codegen.h @@ -10,6 +10,7 @@ #include "nasal_builtin.h" #include "coroutine.h" +#include "bits_lib.h" #include "math_lib.h" #include "fg_props.h"