mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
woot
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.DS_Store
|
||||
zig-cache
|
||||
*.wasm
|
||||
35
.vscode/launch.json
vendored
Normal file
35
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Test",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/zig-cache/bin/test",
|
||||
"args": ["prevent-panic-by-passing-a-placeholder-arg"],
|
||||
"preLaunchTask": "test",
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "lldb"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/zig-cache/bin/esdev",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "lldb",
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"logging": {
|
||||
"moduleLoad": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
40
.vscode/tasks.json
vendored
Normal file
40
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"type": "shell",
|
||||
"command": "zig build",
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "run",
|
||||
"type": "process",
|
||||
"command": "zig",
|
||||
"args": ["run", "${file}"],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"showReuseMessage": false,
|
||||
"clear": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "test",
|
||||
"type": "process",
|
||||
"command": "zig",
|
||||
"args": ["test", "${file}", "-femit-bin=zig-cache/bin/test"],
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"showReuseMessage": false,
|
||||
"clear": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
28
build.zig
Normal file
28
build.zig
Normal file
@@ -0,0 +1,28 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.build.Builder) void {
|
||||
// Standard target options allows the person running `zig build` to choose
|
||||
// what target to build for. Here we do not override the defaults, which
|
||||
// means any target is allowed, and the default is native. Other options
|
||||
// for restricting supported target set are available.
|
||||
const target = b.standardTargetOptions(.{});
|
||||
|
||||
// Standard release options allow the person running `zig build` to select
|
||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
||||
const mode = b.standardReleaseOptions();
|
||||
|
||||
const exe = b.addExecutable("esdev", "src/main.zig");
|
||||
exe.setTarget(target);
|
||||
exe.setBuildMode(mode);
|
||||
exe.addLibPath("/usr/local/lib");
|
||||
exe.install();
|
||||
|
||||
const run_cmd = exe.run();
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
if (b.args) |args| {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
const run_step = b.step("run", "Run the app");
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
176
src/lexer/js_lexer.zig
Normal file
176
src/lexer/js_lexer.zig
Normal file
@@ -0,0 +1,176 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const T = enum(u8) {
|
||||
t_end_of_file,
|
||||
t_syntax_error,
|
||||
|
||||
// "#!/usr/bin/env node"
|
||||
t_hashbang,
|
||||
|
||||
// literals
|
||||
t_no_substitution_template_literal, // contents are in lexer.string_literal ([]uint16)
|
||||
t_numeric_literal, // contents are in lexer.number (float64)
|
||||
t_string_literal, // contents are in lexer.string_literal ([]uint16)
|
||||
t_big_integer_literal, // contents are in lexer.identifier (string)
|
||||
|
||||
// pseudo-literals
|
||||
t_template_head, // contents are in lexer.string_literal ([]uint16)
|
||||
t_template_middle, // contents are in lexer.string_literal ([]uint16)
|
||||
t_template_tail, // contents are in lexer.string_literal ([]uint16)
|
||||
|
||||
// punctuation
|
||||
t_ampersand,
|
||||
t_ampersand_ampersand,
|
||||
t_asterisk,
|
||||
t_asterisk_asterisk,
|
||||
t_at,
|
||||
t_bar,
|
||||
t_bar_bar,
|
||||
t_caret,
|
||||
t_close_brace,
|
||||
t_close_bracket,
|
||||
t_close_paren,
|
||||
t_colon,
|
||||
t_comma,
|
||||
t_dot,
|
||||
t_dot_dot_dot,
|
||||
t_equals_equals,
|
||||
t_equals_equals_equals,
|
||||
t_equals_greater_than,
|
||||
t_exclamation,
|
||||
t_exclamation_equals,
|
||||
t_exclamation_equals_equals,
|
||||
t_greater_than,
|
||||
t_greater_than_equals,
|
||||
t_greater_than_greater_than,
|
||||
t_greater_than_greater_than_greater_than,
|
||||
t_less_than,
|
||||
t_less_than_equals,
|
||||
t_less_than_less_than,
|
||||
t_minus,
|
||||
t_minus_minus,
|
||||
t_open_brace,
|
||||
t_open_bracket,
|
||||
t_open_paren,
|
||||
t_percent,
|
||||
t_plus,
|
||||
t_plus_plus,
|
||||
t_question,
|
||||
t_question_dot,
|
||||
t_question_question,
|
||||
t_semicolon,
|
||||
t_slash,
|
||||
t_tilde,
|
||||
|
||||
// assignments (keep in sync with is_assign() below)
|
||||
t_ampersand_ampersand_equals,
|
||||
t_ampersand_equals,
|
||||
t_asterisk_asterisk_equals,
|
||||
t_asterisk_equals,
|
||||
t_bar_bar_equals,
|
||||
t_bar_equals,
|
||||
t_caret_equals,
|
||||
t_equals,
|
||||
t_greater_than_greater_than_equals,
|
||||
t_greater_than_greater_than_greater_than_equals,
|
||||
t_less_than_less_than_equals,
|
||||
t_minus_equals,
|
||||
t_percent_equals,
|
||||
t_plus_equals,
|
||||
t_question_question_equals,
|
||||
t_slash_equals,
|
||||
|
||||
// class-private fields and methods
|
||||
t_private_identifier,
|
||||
|
||||
// identifiers
|
||||
t_identifier, // contents are in lexer.identifier (string)
|
||||
t_escaped_keyword, // a keyword that has been escaped as an identifer
|
||||
|
||||
// reserved words
|
||||
t_break,
|
||||
t_case,
|
||||
t_catch,
|
||||
t_class,
|
||||
t_const,
|
||||
t_continue,
|
||||
t_debugger,
|
||||
t_default,
|
||||
t_delete,
|
||||
t_do,
|
||||
t_else,
|
||||
t_enum,
|
||||
t_export,
|
||||
t_extends,
|
||||
t_false,
|
||||
t_finally,
|
||||
t_for,
|
||||
t_function,
|
||||
t_if,
|
||||
t_import,
|
||||
t_in,
|
||||
t_instanceof,
|
||||
t_new,
|
||||
t_null,
|
||||
t_return,
|
||||
t_super,
|
||||
t_switch,
|
||||
t_this,
|
||||
t_throw,
|
||||
t_true,
|
||||
t_try,
|
||||
t_typeof,
|
||||
t_var,
|
||||
t_void,
|
||||
t_while,
|
||||
t_with,
|
||||
|
||||
pub fn isAssign() bool {
|
||||
return self >= T.t_ampersand_ampersand_equals and self <= T.t_slash_equals;
|
||||
}
|
||||
|
||||
pub fn isReservedWord() bool {
|
||||
return self >= T.t_break and self <= T.t_with;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Keywords = std.ComptimeStringMap(T, .{
|
||||
.{ "break", .t_break },
|
||||
.{ "case", .t_case },
|
||||
.{ "catch", .t_catch },
|
||||
.{ "class", .t_class },
|
||||
.{ "const", .t_const },
|
||||
.{ "continue", .t_continue },
|
||||
.{ "debugger", .t_debugger },
|
||||
.{ "default", .t_default },
|
||||
.{ "delete", .t_delete },
|
||||
.{ "do", .t_do },
|
||||
.{ "else", .t_else },
|
||||
.{ "enum", .t_enum },
|
||||
.{ "export", .t_export },
|
||||
.{ "extends", .t_extends },
|
||||
.{ "false", .t_false },
|
||||
.{ "finally", .t_finally },
|
||||
.{ "for", .t_for },
|
||||
.{ "function", .t_function },
|
||||
.{ "if", .t_if },
|
||||
.{ "import", .t_import },
|
||||
.{ "in", .t_in },
|
||||
.{ "instanceof", .t_instanceof },
|
||||
.{ "new", .t_new },
|
||||
.{ "null", .t_null },
|
||||
.{ "return", .t_return },
|
||||
.{ "super", .t_super },
|
||||
.{ "switch", .t_switch },
|
||||
.{ "this", .t_this },
|
||||
.{ "throw", .t_throw },
|
||||
.{ "true", .t_true },
|
||||
.{ "try", .t_try },
|
||||
.{ "typeof", .t_typeof },
|
||||
.{ "var", .t_var },
|
||||
.{ "void", .t_void },
|
||||
.{ "while", .t_while },
|
||||
.{ "with", .t_with },
|
||||
});
|
||||
|
||||
const Lexer = struct {};
|
||||
103
src/logger/logger.zig
Normal file
103
src/logger/logger.zig
Normal file
@@ -0,0 +1,103 @@
|
||||
const std = @import("std");
|
||||
|
||||
const expect = std.testing.expect;
|
||||
|
||||
const ArrayList = std.ArrayList;
|
||||
|
||||
pub const Msg = struct {
|
||||
pub const Kind = enum {
|
||||
err,
|
||||
warn,
|
||||
note,
|
||||
debug,
|
||||
|
||||
pub fn string(self: Kind) []const u8 {
|
||||
return switch (self) {
|
||||
.err => "error",
|
||||
.warn => "warn",
|
||||
.note => "note",
|
||||
.debug => "debug",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Location = struct {
|
||||
file: []u8,
|
||||
namespace: []u8 = "file",
|
||||
line: i32 = 1, // 1-based
|
||||
column: i32 = 0, // 0-based, in bytes
|
||||
length: u32 = 0, // in bytes
|
||||
line_text: ?[]u8,
|
||||
suggestion: ?[]u8,
|
||||
|
||||
pub fn init(file: []u8, namespace: []u8, line: i32, column: i32, length: u32, line_text: ?[]u8, suggestion: ?[]u8) Location {
|
||||
return Location{
|
||||
.file = file,
|
||||
.namespace = namespace,
|
||||
.line = line,
|
||||
.column = column,
|
||||
.length = length,
|
||||
.line_text = line_text,
|
||||
.suggestion = suggestion,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn init_file(file: []u8, line: i32, column: i32, length: u32, line_text: ?[]u8, suggestion: ?[]u8) Location {
|
||||
var namespace = "file".*;
|
||||
return Location{
|
||||
.file = file,
|
||||
.namespace = &namespace,
|
||||
.line = line,
|
||||
.column = column,
|
||||
.length = length,
|
||||
.line_text = line_text,
|
||||
.suggestion = suggestion,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Data = struct { text: []u8, location: *Msg.Location };
|
||||
|
||||
kind: Kind,
|
||||
data: Data,
|
||||
};
|
||||
|
||||
pub const Log = struct {
|
||||
debug: bool = false,
|
||||
warnings: u8 = 0,
|
||||
errors: u8 = 0,
|
||||
msgs: ArrayList(Msg),
|
||||
|
||||
pub fn add_msg(self: *Log, msg: Msg) !void {
|
||||
try self.msgs.append(msg);
|
||||
}
|
||||
|
||||
pub fn print(self: *Log) void {
|
||||
if (self.msgs.items.len > 0) {
|
||||
var msg: Msg = self.msgs.items[0];
|
||||
std.debug.print("\n\n{s}: {s}\n{s}\n{s}:{}:{}", .{ msg.kind.string(), msg.data.text, msg.data.location.line_text, msg.data.location.file, msg.data.location.line, msg.data.location.column });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const Source = struct { index: u32, contents: []u8,
|
||||
// An identifier that is mixed in to automatically-generated symbol names to
|
||||
// improve readability. For example, if the identifier is "util" then the
|
||||
// symbol for an "export default" statement will be called "util_default".
|
||||
identifier_name: []u8 };
|
||||
|
||||
test "print msg" {
|
||||
var log = Log{ .msgs = ArrayList(Msg).init(std.testing.allocator) };
|
||||
defer log.msgs.deinit();
|
||||
var filename = "test.js".*;
|
||||
var syntax = "for(i = 0;)".*;
|
||||
var err = "invalid syntax".*;
|
||||
var namespace = "file".*;
|
||||
|
||||
try log.add_msg(Msg{
|
||||
.kind = .err,
|
||||
.data = Msg.Data{ .location = &Msg.Location.init_file(&filename, 1, 3, 0, &syntax, ""), .text = &err },
|
||||
});
|
||||
|
||||
log.print();
|
||||
}
|
||||
6
src/main.zig
Normal file
6
src/main.zig
Normal file
@@ -0,0 +1,6 @@
|
||||
const std = @import("std");
|
||||
const lex = @import("lexer/js_lexer.zig");
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
std.log.info("All your codebase are belong to us. {s}", .{lex.Keywords.get("hey")});
|
||||
}
|
||||
Reference in New Issue
Block a user