aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-01-29 23:52:19 -0800
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-01-29 23:52:19 -0800
commit1489e489504839c04b75f66337daf3a58bab5d42 (patch)
treec47dfbb172b91668d903372ac91188579297a0a5
parent5922ba29acab512ff0aab51e64199d86f148c020 (diff)
downloadbun-1489e489504839c04b75f66337daf3a58bab5d42.tar.gz
bun-1489e489504839c04b75f66337daf3a58bab5d42.tar.zst
bun-1489e489504839c04b75f66337daf3a58bab5d42.zip
Slight tweaks to TOML parser
-rw-r--r--src/javascript/jsc/javascript.zig104
-rw-r--r--src/toml/toml_lexer.zig11
-rw-r--r--src/toml/toml_parser.zig32
3 files changed, 134 insertions, 13 deletions
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig
index 639736f91..7cdb49004 100644
--- a/src/javascript/jsc/javascript.zig
+++ b/src/javascript/jsc/javascript.zig
@@ -599,6 +599,27 @@ pub const Bun = struct {
return JSValue.jsUndefined().asRef();
}
+ pub fn readAllStdinSync(
+ _: void,
+ ctx: js.JSContextRef,
+ _: js.JSObjectRef,
+ _: js.JSObjectRef,
+ _: []const js.JSValueRef,
+ exception: js.ExceptionRef,
+ ) js.JSValueRef {
+ var stack = std.heap.stackFallback(2048, getAllocator(ctx));
+ var allocator = stack.get();
+
+ var stdin = std.io.getStdIn();
+ var result = stdin.readToEndAlloc(allocator, std.math.maxInt(u32)) catch |err| {
+ JSError(undefined, "{s} reading stdin", .{@errorName(err)}, ctx, exception);
+ return null;
+ };
+ var out = ZigString.init(result);
+ out.detectEncoding();
+ return out.toValueGC(ctx.ptr()).asObjectRef();
+ }
+
var public_path_temp_str: [std.fs.MAX_PATH_BYTES]u8 = undefined;
pub fn getPublicPathJS(
@@ -716,6 +737,10 @@ pub const Bun = struct {
.rfn = Bun.shrink,
.ts = d.ts{},
},
+ .readAllStdinSync = .{
+ .rfn = Bun.readAllStdinSync,
+ .ts = d.ts{},
+ },
},
.{
.main = .{
@@ -752,6 +777,10 @@ pub const Bun = struct {
.get = getTranspilerConstructor,
.ts = d.ts{ .name = "Transpiler", .@"return" = "Transpiler.prototype" },
},
+ .TOML = .{
+ .get = getTOMLObject,
+ .ts = d.ts{ .name = "TOML", .@"return" = "TOML.prototype" },
+ },
},
);
@@ -765,6 +794,16 @@ pub const Bun = struct {
return js.JSObjectMake(ctx, Transpiler.TranspilerConstructor.get().?[0], null);
}
+ pub fn getTOMLObject(
+ _: void,
+ ctx: js.JSContextRef,
+ _: js.JSValueRef,
+ _: js.JSStringRef,
+ _: js.ExceptionRef,
+ ) js.JSValueRef {
+ return js.JSObjectMake(ctx, TOML.Class.get().?[0], null);
+ }
+
// For testing the segfault handler
pub fn __debug__doSegfault(
_: void,
@@ -779,6 +818,67 @@ pub const Bun = struct {
Reporter.globalError(error.SegfaultTest);
}
+ pub const TOML = struct {
+ const TOMLParser = @import("../../toml/toml_parser.zig").TOML;
+ pub const Class = NewClass(
+ void,
+ .{
+ .name = "TOML",
+ .read_only = true,
+ },
+ .{
+ .parse = .{
+ .rfn = TOML.parse,
+ },
+ },
+ .{},
+ );
+
+ pub fn parse(
+ // this
+ _: void,
+ ctx: js.JSContextRef,
+ // function
+ _: js.JSObjectRef,
+ // thisObject
+ _: js.JSObjectRef,
+ arguments: []const js.JSValueRef,
+ exception: js.ExceptionRef,
+ ) js.JSValueRef {
+ var arena = std.heap.ArenaAllocator.init(getAllocator(ctx));
+ var allocator = arena.allocator();
+ defer arena.deinit();
+ var log = logger.Log.init(default_allocator);
+ var input_str = ZigString.init("");
+ JSValue.fromRef(arguments[0]).toZigString(&input_str, ctx.ptr());
+ var needs_deinit = false;
+ var input = input_str.slice();
+ if (input_str.is16Bit()) {
+ input = std.fmt.allocPrint(allocator, "{}", .{input_str}) catch unreachable;
+ needs_deinit = true;
+ }
+ var source = logger.Source.initPathString("input.toml", input);
+ var parse_result = TOMLParser.parse(&source, &log, allocator) catch {
+ exception.* = log.toJS(ctx.ptr(), default_allocator, "Failed to parse toml").asObjectRef();
+ return null;
+ };
+
+ // for now...
+ var buffer_writer = try js_printer.BufferWriter.init(allocator);
+ var writer = js_printer.BufferPrinter.init(buffer_writer);
+ _ = js_printer.printJSON(*js_printer.BufferPrinter, &writer, parse_result, &source) catch {
+ exception.* = log.toJS(ctx.ptr(), default_allocator, "Failed to print toml").asObjectRef();
+ return null;
+ };
+
+ var slice = writer.ctx.buffer.toOwnedSliceLeaky();
+ var out = ZigString.init(slice);
+
+ const out_value = js.JSValueMakeFromJSONString(ctx, out.toJSStringRef());
+ return out_value;
+ }
+ };
+
/// EnvironmentVariables is runtime defined.
/// Also, you can't iterate over process.env normally since it only exists at build-time otherwise
// This is aliased to Bun.env
@@ -1381,7 +1481,7 @@ pub const VirtualMachine = struct {
} else if (vm.node_modules == null and strings.eqlComptime(_specifier, Runtime.Runtime.Imports.Name)) {
return ResolvedSource{
.allocator = null,
- .source_code = ZigString.init(Runtime.Runtime.sourceContent()),
+ .source_code = ZigString.init(Runtime.Runtime.sourceContent(false)),
.specifier = ZigString.init(Runtime.Runtime.Imports.Name),
.source_url = ZigString.init(Runtime.Runtime.Imports.Name),
.hash = Runtime.Runtime.versionHash(),
@@ -1483,7 +1583,7 @@ pub const VirtualMachine = struct {
const loader = vm.bundler.options.loaders.get(path.name.ext) orelse .file;
switch (loader) {
- .js, .jsx, .ts, .tsx, .json => {
+ .js, .jsx, .ts, .tsx, .json, .toml => {
vm.transpiled_count += 1;
vm.bundler.resetStore();
const hash = http.Watcher.getHash(path.text);
diff --git a/src/toml/toml_lexer.zig b/src/toml/toml_lexer.zig
index 217bd8fd3..bb13d1658 100644
--- a/src/toml/toml_lexer.zig
+++ b/src/toml/toml_lexer.zig
@@ -45,6 +45,8 @@ pub const T = enum {
t_plus,
t_minus,
+
+ t_empty_array,
};
pub const Lexer = struct {
@@ -527,6 +529,12 @@ pub const Lexer = struct {
if (lexer.code_point == '[' and lexer.allow_double_bracket) {
lexer.step();
lexer.token = T.t_open_bracket_double;
+ return;
+ }
+
+ if (lexer.code_point == ']') {
+ lexer.step();
+ lexer.token = T.t_empty_array;
}
},
']' => {
@@ -770,7 +778,7 @@ pub const Lexer = struct {
try lexer.parseNumericLiteralOrDot();
},
- 'a'...'z', 'A'...'Z', '$', '_' => {
+ '@', 'a'...'z', 'A'...'Z', '$', '_' => {
lexer.step();
while (isIdentifierPart(lexer.code_point)) {
lexer.step();
@@ -1168,6 +1176,7 @@ pub fn isIdentifierPart(code_point: CodePoint) bool {
'$',
'_',
'-',
+ ':',
=> true,
else => false,
};
diff --git a/src/toml/toml_parser.zig b/src/toml/toml_parser.zig
index 9fb01882f..8f7130a1a 100644
--- a/src/toml/toml_parser.zig
+++ b/src/toml/toml_parser.zig
@@ -250,17 +250,24 @@ pub const TOML = struct {
pub fn parseAssignment(p: *TOML, obj: *E.Object, allocator: std.mem.Allocator) anyerror!void {
p.lexer.allow_double_bracket = false;
var rope = try p.parseKey(allocator);
- try p.lexer.expectAssignment();
- obj.setRope(rope, p.allocator, try p.parseValue()) catch |err| {
- switch (err) {
- error.Clobber => {
- try p.lexer.addDefaultError("Cannot redefine key");
- return error.SyntaxError;
- },
- else => return err,
- }
- };
+ const is_array = p.lexer.token == .t_empty_array;
+ if (is_array) {
+ try p.lexer.next();
+ }
+
+ try p.lexer.expectAssignment();
+ if (!is_array) {
+ obj.setRope(rope, p.allocator, try p.parseValue()) catch |err| {
+ switch (err) {
+ error.Clobber => {
+ try p.lexer.addDefaultError("Cannot redefine key");
+ return error.SyntaxError;
+ },
+ else => return err,
+ }
+ };
+ } else {}
p.lexer.allow_double_bracket = true;
}
@@ -344,6 +351,11 @@ pub const TOML = struct {
try p.lexer.expect(.t_close_brace);
return expr;
},
+ .t_empty_array => {
+ try p.lexer.next();
+ p.lexer.allow_double_bracket = true;
+ return p.e(E.Array{}, loc);
+ },
.t_open_bracket => {
try p.lexer.next();
var is_single_line = !p.lexer.has_newline_before;