OR-1 dataflow CPU sketch
at main 140 lines 4.3 kB view raw
1#include "./conversions.h" 2#include "./addon_data.h" 3#include "tree_sitter/api.h" 4 5#include <cmath> 6#include <napi.h> 7 8using namespace Napi; 9 10namespace node_tree_sitter { 11 12static const unsigned BYTES_PER_CHARACTER = 2; 13 14void InitConversions(Napi::Env env, Napi::Object exports) { 15 auto *data = env.GetInstanceData<AddonData>(); 16 17 auto js_point_transfer_buffer = Uint32Array::New(env, 2); 18 data->point_transfer_buffer = js_point_transfer_buffer.Data(); 19 20 exports["pointTransferArray"] = js_point_transfer_buffer; 21} 22 23void TransferPoint(Napi::Env env, const TSPoint &point) { 24 auto *data = env.GetInstanceData<AddonData>(); 25 data->point_transfer_buffer[0] = point.row; 26 data->point_transfer_buffer[1] = point.column / 2; 27} 28 29Napi::Object RangeToJS(Napi::Env env, const TSRange &range) { 30 Object result = Object::New(env); 31 result.Set("startPosition", PointToJS(env, range.start_point)); 32 result.Set("startIndex", ByteCountToJS(env, range.start_byte)); 33 result.Set("endPosition", PointToJS(env, range.end_point)); 34 result.Set("endIndex", ByteCountToJS(env, range.end_byte)); 35 return result; 36} 37 38Napi::Maybe<TSRange> RangeFromJS(const Napi::Value& arg) { 39 Env env = arg.Env(); 40 if (!arg.IsObject()) { 41 TypeError::New(env, "Range must be a {startPosition, endPosition, startIndex, endIndex} object").ThrowAsJavaScriptException(); 42 return Napi::Nothing<TSRange>(); 43 } 44 45 TSRange result; 46 47 auto js_range = arg.As<Object>(); 48 49 #define INIT(field, key, Convert) { \ 50 auto value = js_range.Get(key); \ 51 if (value.IsEmpty()) { \ 52 TypeError::New(env, "Range must be a {startPosition, endPosition, startIndex, endIndex} object").ThrowAsJavaScriptException(); \ 53 return Napi::Nothing<TSRange>(); \ 54 } \ 55 auto field = Convert(value); \ 56 if (field.IsJust()) { \ 57 result.field = field.Unwrap(); \ 58 } else { \ 59 return Napi::Nothing<TSRange>(); \ 60 } \ 61 } 62 63 INIT(start_point, "startPosition", PointFromJS); 64 INIT(end_point, "endPosition", PointFromJS); 65 INIT(start_byte, "startIndex", ByteCountFromJS); 66 INIT(end_byte, "endIndex", ByteCountFromJS); 67 68 #undef INIT 69 70 return Napi::Just(result); 71} 72 73Napi::Object PointToJS(Napi::Env env, const TSPoint &point) { 74 Object result = Object::New(env); 75 result["row"] = Number::New(env, point.row); 76 result["column"] = ByteCountToJS(env, point.column); 77 return result; 78} 79 80Napi::Maybe<TSPoint> PointFromJS(const Napi::Value& arg) { 81 Env env = arg.Env(); 82 83 if (!arg.IsObject()) { 84 TypeError::New(env, "Point must be a {row, column} object").ThrowAsJavaScriptException(); 85 return Napi::Nothing<TSPoint>(); 86 } 87 auto js_point = arg.As<Object>(); 88 89 auto js_row = js_point.Get("row").As<Number>(); 90 if (!js_row.IsNumber()) { 91 TypeError::New(env, "Point must be a {row, column} object").ThrowAsJavaScriptException(); 92 return Napi::Nothing<TSPoint>(); 93 } 94 95 auto js_column = js_point.Get("column").As<Number>(); 96 if (!js_column.IsNumber()) { 97 TypeError::New(env, "Point must be a {row, column} object").ThrowAsJavaScriptException(); 98 return Napi::Nothing<TSPoint>(); 99 } 100 101 uint32_t row; 102 if (!std::isfinite(js_row.DoubleValue())) { 103 row = UINT32_MAX; 104 } else if (js_row.IsNumber()) { 105 row = js_row.Uint32Value(); 106 } else { 107 TypeError::New(env, "Point.row must be a number").ThrowAsJavaScriptException(); 108 return Napi::Nothing<TSPoint>(); 109 } 110 111 uint32_t column; 112 if (!std::isfinite(js_column.DoubleValue())) { 113 column = UINT32_MAX; 114 } else if (js_column.IsNumber()) { 115 column = js_column.Uint32Value() * BYTES_PER_CHARACTER; 116 } else { 117 TypeError::New(env, "Point.column must be a number").ThrowAsJavaScriptException(); 118 return Napi::Nothing<TSPoint>(); 119 } 120 121 return Napi::Just<TSPoint>({row, column}); 122} 123 124Napi::Number ByteCountToJS(Napi::Env env, uint32_t byte_count) { 125 return Number::New(env, byte_count / BYTES_PER_CHARACTER); 126} 127 128Napi::Maybe<uint32_t> ByteCountFromJS(const Napi::Value &arg) { 129 Napi::Env env = arg.Env(); 130 131 if (!arg.IsNumber()) { 132 TypeError::New(env, "Character index must be a number").ThrowAsJavaScriptException(); 133 return Napi::Nothing<uint32_t>(); 134 } 135 auto result = arg.As<Number>(); 136 137 return Napi::Just<uint32_t>(result.Uint32Value() * BYTES_PER_CHARACTER); 138} 139 140} // namespace node_tree_sitter