Merge pull request #4025 from ziglang/Vexu-stage-2-cimport
Use self hosted translate-c for cImport
This commit is contained in:
commit
576320e6d5
@ -448,7 +448,6 @@ set(ZIG_SOURCES
|
|||||||
"${CMAKE_SOURCE_DIR}/src/bigfloat.cpp"
|
"${CMAKE_SOURCE_DIR}/src/bigfloat.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/src/bigint.cpp"
|
"${CMAKE_SOURCE_DIR}/src/bigint.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/src/buffer.cpp"
|
"${CMAKE_SOURCE_DIR}/src/buffer.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/src/c_tokenizer.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/src/cache_hash.cpp"
|
"${CMAKE_SOURCE_DIR}/src/cache_hash.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/src/codegen.cpp"
|
"${CMAKE_SOURCE_DIR}/src/codegen.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/src/compiler.cpp"
|
"${CMAKE_SOURCE_DIR}/src/compiler.cpp"
|
||||||
@ -465,7 +464,6 @@ set(ZIG_SOURCES
|
|||||||
"${CMAKE_SOURCE_DIR}/src/range_set.cpp"
|
"${CMAKE_SOURCE_DIR}/src/range_set.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/src/target.cpp"
|
"${CMAKE_SOURCE_DIR}/src/target.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"
|
"${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/src/translate_c.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/src/util.cpp"
|
"${CMAKE_SOURCE_DIR}/src/util.cpp"
|
||||||
"${ZIG_SOURCES_MEM_PROFILE}"
|
"${ZIG_SOURCES_MEM_PROFILE}"
|
||||||
)
|
)
|
||||||
|
@ -224,7 +224,7 @@ test "crypto.chacha20 test vector sunscreen" {
|
|||||||
// Chacha20 is self-reversing.
|
// Chacha20 is self-reversing.
|
||||||
var plaintext: [114]u8 = undefined;
|
var plaintext: [114]u8 = undefined;
|
||||||
chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce);
|
chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce);
|
||||||
testing.expect(mem.compare(u8, input, &plaintext) == mem.Compare.Equal);
|
testing.expect(mem.order(u8, input, &plaintext) == .eq);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7
|
// https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7
|
||||||
|
@ -70,12 +70,12 @@ const HeaderEntry = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sort lexicographically on header name
|
// Sort lexicographically on header name
|
||||||
return mem.compare(u8, a.name, b.name) == mem.Compare.LessThan;
|
return mem.order(u8, a.name, b.name) == .lt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort lexicographically on header value
|
// Sort lexicographically on header value
|
||||||
if (!mem.eql(u8, a.value, b.value)) {
|
if (!mem.eql(u8, a.value, b.value)) {
|
||||||
return mem.compare(u8, a.value, b.value) == mem.Compare.LessThan;
|
return mem.order(u8, a.value, b.value) == .lt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Doesn't matter here; need to pick something for sort consistency
|
// Doesn't matter here; need to pick something for sort consistency
|
||||||
|
@ -926,9 +926,6 @@ test "minInt and maxInt" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "max value type" {
|
test "max value type" {
|
||||||
// If the type of maxInt(i32) was i32 then this implicit cast to
|
|
||||||
// u32 would not work. But since the value is a number literal,
|
|
||||||
// it works fine.
|
|
||||||
const x: u32 = maxInt(i32);
|
const x: u32 = maxInt(i32);
|
||||||
testing.expect(x == 2147483647);
|
testing.expect(x == 2147483647);
|
||||||
}
|
}
|
||||||
@ -944,7 +941,32 @@ test "math.mulWide" {
|
|||||||
testing.expect(mulWide(u8, 100, 100) == 10000);
|
testing.expect(mulWide(u8, 100, 100) == 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Not to be confused with `std.mem.Compare`.
|
/// See also `CompareOperator`.
|
||||||
|
pub const Order = enum {
|
||||||
|
/// Less than (`<`)
|
||||||
|
lt,
|
||||||
|
|
||||||
|
/// Equal (`==`)
|
||||||
|
eq,
|
||||||
|
|
||||||
|
/// Greater than (`>`)
|
||||||
|
gt,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Given two numbers, this function returns the order they are with respect to each other.
|
||||||
|
pub fn order(a: var, b: var) Order {
|
||||||
|
if (a == b) {
|
||||||
|
return .eq;
|
||||||
|
} else if (a < b) {
|
||||||
|
return .lt;
|
||||||
|
} else if (a > b) {
|
||||||
|
return .gt;
|
||||||
|
} else {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See also `Order`.
|
||||||
pub const CompareOperator = enum {
|
pub const CompareOperator = enum {
|
||||||
/// Less than (`<`)
|
/// Less than (`<`)
|
||||||
lt,
|
lt,
|
||||||
@ -979,7 +1001,7 @@ pub fn compare(a: var, op: CompareOperator, b: var) bool {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
test "math.lt, et al < <= > >= between signed and unsigned" {
|
test "compare between signed and unsigned" {
|
||||||
testing.expect(compare(@as(i8, -1), .lt, @as(u8, 255)));
|
testing.expect(compare(@as(i8, -1), .lt, @as(u8, 255)));
|
||||||
testing.expect(compare(@as(i8, 2), .gt, @as(u8, 1)));
|
testing.expect(compare(@as(i8, 2), .gt, @as(u8, 1)));
|
||||||
testing.expect(!compare(@as(i8, -1), .gte, @as(u8, 255)));
|
testing.expect(!compare(@as(i8, -1), .gte, @as(u8, 255)));
|
||||||
|
@ -239,12 +239,6 @@ pub const Allocator = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Compare = enum {
|
|
||||||
LessThan,
|
|
||||||
Equal,
|
|
||||||
GreaterThan,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Copy all of source into dest at position 0.
|
/// Copy all of source into dest at position 0.
|
||||||
/// dest.len must be >= source.len.
|
/// dest.len must be >= source.len.
|
||||||
/// dest.ptr must be <= src.ptr.
|
/// dest.ptr must be <= src.ptr.
|
||||||
@ -297,46 +291,30 @@ test "mem.secureZero" {
|
|||||||
testing.expectEqualSlices(u8, a[0..], b[0..]);
|
testing.expectEqualSlices(u8, a[0..], b[0..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compare(comptime T: type, lhs: []const T, rhs: []const T) Compare {
|
pub fn order(comptime T: type, lhs: []const T, rhs: []const T) math.Order {
|
||||||
const n = math.min(lhs.len, rhs.len);
|
const n = math.min(lhs.len, rhs.len);
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (i < n) : (i += 1) {
|
while (i < n) : (i += 1) {
|
||||||
if (lhs[i] == rhs[i]) {
|
switch (math.order(lhs[i], rhs[i])) {
|
||||||
continue;
|
.eq => continue,
|
||||||
} else if (lhs[i] < rhs[i]) {
|
.lt => return .lt,
|
||||||
return Compare.LessThan;
|
.gt => return .gt,
|
||||||
} else if (lhs[i] > rhs[i]) {
|
|
||||||
return Compare.GreaterThan;
|
|
||||||
} else {
|
|
||||||
unreachable;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return math.order(lhs.len, rhs.len);
|
||||||
if (lhs.len == rhs.len) {
|
|
||||||
return Compare.Equal;
|
|
||||||
} else if (lhs.len < rhs.len) {
|
|
||||||
return Compare.LessThan;
|
|
||||||
} else if (lhs.len > rhs.len) {
|
|
||||||
return Compare.GreaterThan;
|
|
||||||
}
|
|
||||||
unreachable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "mem.compare" {
|
test "order" {
|
||||||
testing.expect(compare(u8, "abcd", "bee") == Compare.LessThan);
|
testing.expect(order(u8, "abcd", "bee") == .lt);
|
||||||
testing.expect(compare(u8, "abc", "abc") == Compare.Equal);
|
testing.expect(order(u8, "abc", "abc") == .eq);
|
||||||
testing.expect(compare(u8, "abc", "abc0") == Compare.LessThan);
|
testing.expect(order(u8, "abc", "abc0") == .lt);
|
||||||
testing.expect(compare(u8, "", "") == Compare.Equal);
|
testing.expect(order(u8, "", "") == .eq);
|
||||||
testing.expect(compare(u8, "", "a") == Compare.LessThan);
|
testing.expect(order(u8, "", "a") == .lt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if lhs < rhs, false otherwise
|
/// Returns true if lhs < rhs, false otherwise
|
||||||
pub fn lessThan(comptime T: type, lhs: []const T, rhs: []const T) bool {
|
pub fn lessThan(comptime T: type, lhs: []const T, rhs: []const T) bool {
|
||||||
var result = compare(T, lhs, rhs);
|
return order(T, lhs, rhs) == .lt;
|
||||||
if (result == Compare.LessThan) {
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "mem.lessThan" {
|
test "mem.lessThan" {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const std = @import("std.zig");
|
const std = @import("std.zig");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const mem = std.mem; // For mem.Compare
|
const Order = std.math.Order;
|
||||||
|
|
||||||
const Color = enum(u1) {
|
const Color = enum(u1) {
|
||||||
Black,
|
Black,
|
||||||
@ -132,7 +132,7 @@ pub const Node = struct {
|
|||||||
|
|
||||||
pub const Tree = struct {
|
pub const Tree = struct {
|
||||||
root: ?*Node,
|
root: ?*Node,
|
||||||
compareFn: fn (*Node, *Node) mem.Compare,
|
compareFn: fn (*Node, *Node) Order,
|
||||||
|
|
||||||
/// If you have a need for a version that caches this, please file a bug.
|
/// If you have a need for a version that caches this, please file a bug.
|
||||||
pub fn first(tree: *Tree) ?*Node {
|
pub fn first(tree: *Tree) ?*Node {
|
||||||
@ -389,7 +389,7 @@ pub const Tree = struct {
|
|||||||
var new = newconst;
|
var new = newconst;
|
||||||
|
|
||||||
// I assume this can get optimized out if the caller already knows.
|
// I assume this can get optimized out if the caller already knows.
|
||||||
if (tree.compareFn(old, new) != mem.Compare.Equal) return ReplaceError.NotEqual;
|
if (tree.compareFn(old, new) != .eq) return ReplaceError.NotEqual;
|
||||||
|
|
||||||
if (old.getParent()) |parent| {
|
if (old.getParent()) |parent| {
|
||||||
parent.setChild(new, parent.left == old);
|
parent.setChild(new, parent.left == old);
|
||||||
@ -404,7 +404,7 @@ pub const Tree = struct {
|
|||||||
new.* = old.*;
|
new.* = old.*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(tree: *Tree, f: fn (*Node, *Node) mem.Compare) void {
|
pub fn init(tree: *Tree, f: fn (*Node, *Node) Order) void {
|
||||||
tree.root = null;
|
tree.root = null;
|
||||||
tree.compareFn = f;
|
tree.compareFn = f;
|
||||||
}
|
}
|
||||||
@ -469,19 +469,21 @@ fn doLookup(key: *Node, tree: *Tree, pparent: *?*Node, is_left: *bool) ?*Node {
|
|||||||
is_left.* = false;
|
is_left.* = false;
|
||||||
|
|
||||||
while (maybe_node) |node| {
|
while (maybe_node) |node| {
|
||||||
var res: mem.Compare = tree.compareFn(node, key);
|
const res = tree.compareFn(node, key);
|
||||||
if (res == mem.Compare.Equal) {
|
if (res == .eq) {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
pparent.* = node;
|
pparent.* = node;
|
||||||
if (res == mem.Compare.GreaterThan) {
|
switch (res) {
|
||||||
is_left.* = true;
|
.gt => {
|
||||||
maybe_node = node.left;
|
is_left.* = true;
|
||||||
} else if (res == mem.Compare.LessThan) {
|
maybe_node = node.left;
|
||||||
is_left.* = false;
|
},
|
||||||
maybe_node = node.right;
|
.lt => {
|
||||||
} else {
|
is_left.* = false;
|
||||||
unreachable;
|
maybe_node = node.right;
|
||||||
|
},
|
||||||
|
.eq => unreachable, // handled above
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -496,16 +498,16 @@ fn testGetNumber(node: *Node) *testNumber {
|
|||||||
return @fieldParentPtr(testNumber, "node", node);
|
return @fieldParentPtr(testNumber, "node", node);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testCompare(l: *Node, r: *Node) mem.Compare {
|
fn testCompare(l: *Node, r: *Node) Order {
|
||||||
var left = testGetNumber(l);
|
var left = testGetNumber(l);
|
||||||
var right = testGetNumber(r);
|
var right = testGetNumber(r);
|
||||||
|
|
||||||
if (left.value < right.value) {
|
if (left.value < right.value) {
|
||||||
return mem.Compare.LessThan;
|
return .lt;
|
||||||
} else if (left.value == right.value) {
|
} else if (left.value == right.value) {
|
||||||
return mem.Compare.Equal;
|
return .eq;
|
||||||
} else if (left.value > right.value) {
|
} else if (left.value > right.value) {
|
||||||
return mem.Compare.GreaterThan;
|
return .gt;
|
||||||
}
|
}
|
||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ pub const Tree = struct {
|
|||||||
root_node: *Node.Root,
|
root_node: *Node.Root,
|
||||||
arena_allocator: std.heap.ArenaAllocator,
|
arena_allocator: std.heap.ArenaAllocator,
|
||||||
errors: ErrorList,
|
errors: ErrorList,
|
||||||
|
generated: bool = false,
|
||||||
|
|
||||||
pub const TokenList = SegmentedList(Token, 64);
|
pub const TokenList = SegmentedList(Token, 64);
|
||||||
pub const ErrorList = SegmentedList(Error, 0);
|
pub const ErrorList = SegmentedList(Error, 0);
|
||||||
@ -58,6 +59,8 @@ pub const Tree = struct {
|
|||||||
.line_start = start_index,
|
.line_start = start_index,
|
||||||
.line_end = self.source.len,
|
.line_end = self.source.len,
|
||||||
};
|
};
|
||||||
|
if (self.generated)
|
||||||
|
return loc;
|
||||||
const token_start = token.start;
|
const token_start = token.start;
|
||||||
for (self.source[start_index..]) |c, i| {
|
for (self.source[start_index..]) |c, i| {
|
||||||
if (i + start_index == token_start) {
|
if (i + start_index == token_start) {
|
||||||
@ -581,7 +584,7 @@ pub const Node = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const Root = struct {
|
pub const Root = struct {
|
||||||
base: Node = Node {.id = .Root},
|
base: Node = Node{ .id = .Root },
|
||||||
decls: DeclList,
|
decls: DeclList,
|
||||||
eof_token: TokenIndex,
|
eof_token: TokenIndex,
|
||||||
|
|
||||||
@ -604,7 +607,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const VarDecl = struct {
|
pub const VarDecl = struct {
|
||||||
base: Node = Node {.id = .VarDecl},
|
base: Node = Node{ .id = .VarDecl },
|
||||||
doc_comments: ?*DocComment,
|
doc_comments: ?*DocComment,
|
||||||
visib_token: ?TokenIndex,
|
visib_token: ?TokenIndex,
|
||||||
thread_local_token: ?TokenIndex,
|
thread_local_token: ?TokenIndex,
|
||||||
@ -661,7 +664,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Use = struct {
|
pub const Use = struct {
|
||||||
base: Node = Node {.id = .Use},
|
base: Node = Node{ .id = .Use },
|
||||||
doc_comments: ?*DocComment,
|
doc_comments: ?*DocComment,
|
||||||
visib_token: ?TokenIndex,
|
visib_token: ?TokenIndex,
|
||||||
use_token: TokenIndex,
|
use_token: TokenIndex,
|
||||||
@ -688,7 +691,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const ErrorSetDecl = struct {
|
pub const ErrorSetDecl = struct {
|
||||||
base: Node = Node {.id = .ErrorSetDecl},
|
base: Node = Node{ .id = .ErrorSetDecl },
|
||||||
error_token: TokenIndex,
|
error_token: TokenIndex,
|
||||||
decls: DeclList,
|
decls: DeclList,
|
||||||
rbrace_token: TokenIndex,
|
rbrace_token: TokenIndex,
|
||||||
@ -714,7 +717,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const ContainerDecl = struct {
|
pub const ContainerDecl = struct {
|
||||||
base: Node = Node {.id = .ContainerDecl},
|
base: Node = Node{ .id = .ContainerDecl },
|
||||||
layout_token: ?TokenIndex,
|
layout_token: ?TokenIndex,
|
||||||
kind_token: TokenIndex,
|
kind_token: TokenIndex,
|
||||||
init_arg_expr: InitArg,
|
init_arg_expr: InitArg,
|
||||||
@ -801,7 +804,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const ErrorTag = struct {
|
pub const ErrorTag = struct {
|
||||||
base: Node = Node {.id = .ErrorTag},
|
base: Node = Node{ .id = .ErrorTag },
|
||||||
doc_comments: ?*DocComment,
|
doc_comments: ?*DocComment,
|
||||||
name_token: TokenIndex,
|
name_token: TokenIndex,
|
||||||
|
|
||||||
@ -826,7 +829,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Identifier = struct {
|
pub const Identifier = struct {
|
||||||
base: Node = Node {.id = .Identifier},
|
base: Node = Node{ .id = .Identifier },
|
||||||
token: TokenIndex,
|
token: TokenIndex,
|
||||||
|
|
||||||
pub fn iterate(self: *Identifier, index: usize) ?*Node {
|
pub fn iterate(self: *Identifier, index: usize) ?*Node {
|
||||||
@ -843,7 +846,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const FnProto = struct {
|
pub const FnProto = struct {
|
||||||
base: Node = Node {.id = .FnProto},
|
base: Node = Node{ .id = .FnProto },
|
||||||
doc_comments: ?*DocComment,
|
doc_comments: ?*DocComment,
|
||||||
visib_token: ?TokenIndex,
|
visib_token: ?TokenIndex,
|
||||||
fn_token: TokenIndex,
|
fn_token: TokenIndex,
|
||||||
@ -925,7 +928,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const AnyFrameType = struct {
|
pub const AnyFrameType = struct {
|
||||||
base: Node = Node {.id = .AnyFrameType},
|
base: Node = Node{ .id = .AnyFrameType },
|
||||||
anyframe_token: TokenIndex,
|
anyframe_token: TokenIndex,
|
||||||
result: ?Result,
|
result: ?Result,
|
||||||
|
|
||||||
@ -956,7 +959,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const ParamDecl = struct {
|
pub const ParamDecl = struct {
|
||||||
base: Node = Node {.id = .ParamDecl},
|
base: Node = Node{ .id = .ParamDecl },
|
||||||
doc_comments: ?*DocComment,
|
doc_comments: ?*DocComment,
|
||||||
comptime_token: ?TokenIndex,
|
comptime_token: ?TokenIndex,
|
||||||
noalias_token: ?TokenIndex,
|
noalias_token: ?TokenIndex,
|
||||||
@ -989,7 +992,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Block = struct {
|
pub const Block = struct {
|
||||||
base: Node = Node {.id = .Block},
|
base: Node = Node{ .id = .Block },
|
||||||
label: ?TokenIndex,
|
label: ?TokenIndex,
|
||||||
lbrace: TokenIndex,
|
lbrace: TokenIndex,
|
||||||
statements: StatementList,
|
statements: StatementList,
|
||||||
@ -1020,7 +1023,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Defer = struct {
|
pub const Defer = struct {
|
||||||
base: Node = Node {.id = .Defer},
|
base: Node = Node{ .id = .Defer },
|
||||||
defer_token: TokenIndex,
|
defer_token: TokenIndex,
|
||||||
expr: *Node,
|
expr: *Node,
|
||||||
|
|
||||||
@ -1043,7 +1046,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Comptime = struct {
|
pub const Comptime = struct {
|
||||||
base: Node = Node {.id = .Comptime},
|
base: Node = Node{ .id = .Comptime },
|
||||||
doc_comments: ?*DocComment,
|
doc_comments: ?*DocComment,
|
||||||
comptime_token: TokenIndex,
|
comptime_token: TokenIndex,
|
||||||
expr: *Node,
|
expr: *Node,
|
||||||
@ -1067,7 +1070,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Payload = struct {
|
pub const Payload = struct {
|
||||||
base: Node = Node {.id = .Payload},
|
base: Node = Node{ .id = .Payload },
|
||||||
lpipe: TokenIndex,
|
lpipe: TokenIndex,
|
||||||
error_symbol: *Node,
|
error_symbol: *Node,
|
||||||
rpipe: TokenIndex,
|
rpipe: TokenIndex,
|
||||||
@ -1091,7 +1094,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const PointerPayload = struct {
|
pub const PointerPayload = struct {
|
||||||
base: Node = Node {.id = .PointerPayload},
|
base: Node = Node{ .id = .PointerPayload },
|
||||||
lpipe: TokenIndex,
|
lpipe: TokenIndex,
|
||||||
ptr_token: ?TokenIndex,
|
ptr_token: ?TokenIndex,
|
||||||
value_symbol: *Node,
|
value_symbol: *Node,
|
||||||
@ -1116,7 +1119,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const PointerIndexPayload = struct {
|
pub const PointerIndexPayload = struct {
|
||||||
base: Node = Node {.id = .PointerIndexPayload},
|
base: Node = Node{ .id = .PointerIndexPayload },
|
||||||
lpipe: TokenIndex,
|
lpipe: TokenIndex,
|
||||||
ptr_token: ?TokenIndex,
|
ptr_token: ?TokenIndex,
|
||||||
value_symbol: *Node,
|
value_symbol: *Node,
|
||||||
@ -1147,7 +1150,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Else = struct {
|
pub const Else = struct {
|
||||||
base: Node = Node {.id = .Else},
|
base: Node = Node{ .id = .Else },
|
||||||
else_token: TokenIndex,
|
else_token: TokenIndex,
|
||||||
payload: ?*Node,
|
payload: ?*Node,
|
||||||
body: *Node,
|
body: *Node,
|
||||||
@ -1176,7 +1179,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Switch = struct {
|
pub const Switch = struct {
|
||||||
base: Node = Node {.id = .Switch},
|
base: Node = Node{ .id = .Switch },
|
||||||
switch_token: TokenIndex,
|
switch_token: TokenIndex,
|
||||||
expr: *Node,
|
expr: *Node,
|
||||||
|
|
||||||
@ -1208,7 +1211,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const SwitchCase = struct {
|
pub const SwitchCase = struct {
|
||||||
base: Node = Node {.id = .SwitchCase},
|
base: Node = Node{ .id = .SwitchCase },
|
||||||
items: ItemList,
|
items: ItemList,
|
||||||
arrow_token: TokenIndex,
|
arrow_token: TokenIndex,
|
||||||
payload: ?*Node,
|
payload: ?*Node,
|
||||||
@ -1243,7 +1246,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const SwitchElse = struct {
|
pub const SwitchElse = struct {
|
||||||
base: Node = Node {.id = .SwitchElse},
|
base: Node = Node{ .id = .SwitchElse },
|
||||||
token: TokenIndex,
|
token: TokenIndex,
|
||||||
|
|
||||||
pub fn iterate(self: *SwitchElse, index: usize) ?*Node {
|
pub fn iterate(self: *SwitchElse, index: usize) ?*Node {
|
||||||
@ -1260,7 +1263,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const While = struct {
|
pub const While = struct {
|
||||||
base: Node = Node {.id = .While},
|
base: Node = Node{ .id = .While },
|
||||||
label: ?TokenIndex,
|
label: ?TokenIndex,
|
||||||
inline_token: ?TokenIndex,
|
inline_token: ?TokenIndex,
|
||||||
while_token: TokenIndex,
|
while_token: TokenIndex,
|
||||||
@ -1319,7 +1322,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const For = struct {
|
pub const For = struct {
|
||||||
base: Node = Node {.id = .For},
|
base: Node = Node{ .id = .For },
|
||||||
label: ?TokenIndex,
|
label: ?TokenIndex,
|
||||||
inline_token: ?TokenIndex,
|
inline_token: ?TokenIndex,
|
||||||
for_token: TokenIndex,
|
for_token: TokenIndex,
|
||||||
@ -1370,7 +1373,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const If = struct {
|
pub const If = struct {
|
||||||
base: Node = Node {.id = .If},
|
base: Node = Node{ .id = .If },
|
||||||
if_token: TokenIndex,
|
if_token: TokenIndex,
|
||||||
condition: *Node,
|
condition: *Node,
|
||||||
payload: ?*Node,
|
payload: ?*Node,
|
||||||
@ -1413,7 +1416,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const InfixOp = struct {
|
pub const InfixOp = struct {
|
||||||
base: Node = Node {.id = .InfixOp},
|
base: Node = Node{ .id = .InfixOp },
|
||||||
op_token: TokenIndex,
|
op_token: TokenIndex,
|
||||||
lhs: *Node,
|
lhs: *Node,
|
||||||
op: Op,
|
op: Op,
|
||||||
@ -1646,7 +1649,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const FieldInitializer = struct {
|
pub const FieldInitializer = struct {
|
||||||
base: Node = Node {.id = .FieldInitializer},
|
base: Node = Node{ .id = .FieldInitializer },
|
||||||
period_token: TokenIndex,
|
period_token: TokenIndex,
|
||||||
name_token: TokenIndex,
|
name_token: TokenIndex,
|
||||||
expr: *Node,
|
expr: *Node,
|
||||||
@ -1670,7 +1673,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const SuffixOp = struct {
|
pub const SuffixOp = struct {
|
||||||
base: Node = Node {.id = .SuffixOp},
|
base: Node = Node{ .id = .SuffixOp },
|
||||||
lhs: Lhs,
|
lhs: Lhs,
|
||||||
op: Op,
|
op: Op,
|
||||||
rtoken: TokenIndex,
|
rtoken: TokenIndex,
|
||||||
@ -1771,7 +1774,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const GroupedExpression = struct {
|
pub const GroupedExpression = struct {
|
||||||
base: Node = Node {.id = .GroupedExpression},
|
base: Node = Node{ .id = .GroupedExpression },
|
||||||
lparen: TokenIndex,
|
lparen: TokenIndex,
|
||||||
expr: *Node,
|
expr: *Node,
|
||||||
rparen: TokenIndex,
|
rparen: TokenIndex,
|
||||||
@ -1795,7 +1798,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const ControlFlowExpression = struct {
|
pub const ControlFlowExpression = struct {
|
||||||
base: Node = Node {.id = .ControlFlowExpression},
|
base: Node = Node{ .id = .ControlFlowExpression },
|
||||||
ltoken: TokenIndex,
|
ltoken: TokenIndex,
|
||||||
kind: Kind,
|
kind: Kind,
|
||||||
rhs: ?*Node,
|
rhs: ?*Node,
|
||||||
@ -1861,7 +1864,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Suspend = struct {
|
pub const Suspend = struct {
|
||||||
base: Node = Node {.id = .Suspend},
|
base: Node = Node{ .id = .Suspend },
|
||||||
suspend_token: TokenIndex,
|
suspend_token: TokenIndex,
|
||||||
body: ?*Node,
|
body: ?*Node,
|
||||||
|
|
||||||
@ -1890,7 +1893,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const IntegerLiteral = struct {
|
pub const IntegerLiteral = struct {
|
||||||
base: Node = Node {.id = .IntegerLiteral},
|
base: Node = Node{ .id = .IntegerLiteral },
|
||||||
token: TokenIndex,
|
token: TokenIndex,
|
||||||
|
|
||||||
pub fn iterate(self: *IntegerLiteral, index: usize) ?*Node {
|
pub fn iterate(self: *IntegerLiteral, index: usize) ?*Node {
|
||||||
@ -1907,7 +1910,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const EnumLiteral = struct {
|
pub const EnumLiteral = struct {
|
||||||
base: Node = Node {.id = .EnumLiteral},
|
base: Node = Node{ .id = .EnumLiteral },
|
||||||
dot: TokenIndex,
|
dot: TokenIndex,
|
||||||
name: TokenIndex,
|
name: TokenIndex,
|
||||||
|
|
||||||
@ -1925,7 +1928,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const FloatLiteral = struct {
|
pub const FloatLiteral = struct {
|
||||||
base: Node = Node {.id = .FloatLiteral},
|
base: Node = Node{ .id = .FloatLiteral },
|
||||||
token: TokenIndex,
|
token: TokenIndex,
|
||||||
|
|
||||||
pub fn iterate(self: *FloatLiteral, index: usize) ?*Node {
|
pub fn iterate(self: *FloatLiteral, index: usize) ?*Node {
|
||||||
@ -1942,7 +1945,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const BuiltinCall = struct {
|
pub const BuiltinCall = struct {
|
||||||
base: Node = Node {.id = .BuiltinCall},
|
base: Node = Node{ .id = .BuiltinCall },
|
||||||
builtin_token: TokenIndex,
|
builtin_token: TokenIndex,
|
||||||
params: ParamList,
|
params: ParamList,
|
||||||
rparen_token: TokenIndex,
|
rparen_token: TokenIndex,
|
||||||
@ -1968,7 +1971,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const StringLiteral = struct {
|
pub const StringLiteral = struct {
|
||||||
base: Node = Node {.id = .StringLiteral},
|
base: Node = Node{ .id = .StringLiteral },
|
||||||
token: TokenIndex,
|
token: TokenIndex,
|
||||||
|
|
||||||
pub fn iterate(self: *StringLiteral, index: usize) ?*Node {
|
pub fn iterate(self: *StringLiteral, index: usize) ?*Node {
|
||||||
@ -1985,7 +1988,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const MultilineStringLiteral = struct {
|
pub const MultilineStringLiteral = struct {
|
||||||
base: Node = Node {.id = .MultilineStringLiteral},
|
base: Node = Node{ .id = .MultilineStringLiteral },
|
||||||
lines: LineList,
|
lines: LineList,
|
||||||
|
|
||||||
pub const LineList = SegmentedList(TokenIndex, 4);
|
pub const LineList = SegmentedList(TokenIndex, 4);
|
||||||
@ -2004,7 +2007,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const CharLiteral = struct {
|
pub const CharLiteral = struct {
|
||||||
base: Node = Node {.id = .CharLiteral},
|
base: Node = Node{ .id = .CharLiteral },
|
||||||
token: TokenIndex,
|
token: TokenIndex,
|
||||||
|
|
||||||
pub fn iterate(self: *CharLiteral, index: usize) ?*Node {
|
pub fn iterate(self: *CharLiteral, index: usize) ?*Node {
|
||||||
@ -2021,7 +2024,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const BoolLiteral = struct {
|
pub const BoolLiteral = struct {
|
||||||
base: Node = Node {.id = .BoolLiteral},
|
base: Node = Node{ .id = .BoolLiteral },
|
||||||
token: TokenIndex,
|
token: TokenIndex,
|
||||||
|
|
||||||
pub fn iterate(self: *BoolLiteral, index: usize) ?*Node {
|
pub fn iterate(self: *BoolLiteral, index: usize) ?*Node {
|
||||||
@ -2038,7 +2041,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const NullLiteral = struct {
|
pub const NullLiteral = struct {
|
||||||
base: Node = Node {.id = .NullLiteral},
|
base: Node = Node{ .id = .NullLiteral },
|
||||||
token: TokenIndex,
|
token: TokenIndex,
|
||||||
|
|
||||||
pub fn iterate(self: *NullLiteral, index: usize) ?*Node {
|
pub fn iterate(self: *NullLiteral, index: usize) ?*Node {
|
||||||
@ -2055,7 +2058,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const UndefinedLiteral = struct {
|
pub const UndefinedLiteral = struct {
|
||||||
base: Node = Node {.id = .UndefinedLiteral},
|
base: Node = Node{ .id = .UndefinedLiteral },
|
||||||
token: TokenIndex,
|
token: TokenIndex,
|
||||||
|
|
||||||
pub fn iterate(self: *UndefinedLiteral, index: usize) ?*Node {
|
pub fn iterate(self: *UndefinedLiteral, index: usize) ?*Node {
|
||||||
@ -2072,7 +2075,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const AsmOutput = struct {
|
pub const AsmOutput = struct {
|
||||||
base: Node = Node {.id = .AsmOutput},
|
base: Node = Node{ .id = .AsmOutput },
|
||||||
lbracket: TokenIndex,
|
lbracket: TokenIndex,
|
||||||
symbolic_name: *Node,
|
symbolic_name: *Node,
|
||||||
constraint: *Node,
|
constraint: *Node,
|
||||||
@ -2117,7 +2120,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const AsmInput = struct {
|
pub const AsmInput = struct {
|
||||||
base: Node = Node {.id = .AsmInput},
|
base: Node = Node{ .id = .AsmInput },
|
||||||
lbracket: TokenIndex,
|
lbracket: TokenIndex,
|
||||||
symbolic_name: *Node,
|
symbolic_name: *Node,
|
||||||
constraint: *Node,
|
constraint: *Node,
|
||||||
@ -2149,7 +2152,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Asm = struct {
|
pub const Asm = struct {
|
||||||
base: Node = Node {.id = .Asm},
|
base: Node = Node{ .id = .Asm },
|
||||||
asm_token: TokenIndex,
|
asm_token: TokenIndex,
|
||||||
volatile_token: ?TokenIndex,
|
volatile_token: ?TokenIndex,
|
||||||
template: *Node,
|
template: *Node,
|
||||||
@ -2184,7 +2187,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Unreachable = struct {
|
pub const Unreachable = struct {
|
||||||
base: Node = Node {.id = .Unreachable},
|
base: Node = Node{ .id = .Unreachable },
|
||||||
token: TokenIndex,
|
token: TokenIndex,
|
||||||
|
|
||||||
pub fn iterate(self: *Unreachable, index: usize) ?*Node {
|
pub fn iterate(self: *Unreachable, index: usize) ?*Node {
|
||||||
@ -2201,7 +2204,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const ErrorType = struct {
|
pub const ErrorType = struct {
|
||||||
base: Node = Node {.id = .ErrorType},
|
base: Node = Node{ .id = .ErrorType },
|
||||||
token: TokenIndex,
|
token: TokenIndex,
|
||||||
|
|
||||||
pub fn iterate(self: *ErrorType, index: usize) ?*Node {
|
pub fn iterate(self: *ErrorType, index: usize) ?*Node {
|
||||||
@ -2235,7 +2238,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const DocComment = struct {
|
pub const DocComment = struct {
|
||||||
base: Node = Node {.id = .DocComment},
|
base: Node = Node{ .id = .DocComment },
|
||||||
lines: LineList,
|
lines: LineList,
|
||||||
|
|
||||||
pub const LineList = SegmentedList(TokenIndex, 4);
|
pub const LineList = SegmentedList(TokenIndex, 4);
|
||||||
@ -2254,7 +2257,7 @@ pub const Node = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const TestDecl = struct {
|
pub const TestDecl = struct {
|
||||||
base: Node = Node {.id = .TestDecl},
|
base: Node = Node{ .id = .TestDecl },
|
||||||
doc_comments: ?*DocComment,
|
doc_comments: ?*DocComment,
|
||||||
test_token: TokenIndex,
|
test_token: TokenIndex,
|
||||||
name: *Node,
|
name: *Node,
|
||||||
|
@ -643,7 +643,7 @@ fn renderExpression(
|
|||||||
},
|
},
|
||||||
|
|
||||||
.ArrayAccess => |index_expr| {
|
.ArrayAccess => |index_expr| {
|
||||||
const lbracket = tree.prevToken(index_expr.firstToken());
|
const lbracket = tree.nextToken(suffix_op.lhs.node.lastToken());
|
||||||
const rbracket = tree.nextToken(index_expr.lastToken());
|
const rbracket = tree.nextToken(index_expr.lastToken());
|
||||||
|
|
||||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
|
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
|
||||||
|
@ -8,7 +8,7 @@ pub const TokenList = std.SegmentedList(CToken, 32);
|
|||||||
|
|
||||||
pub const CToken = struct {
|
pub const CToken = struct {
|
||||||
id: Id,
|
id: Id,
|
||||||
bytes: []const u8,
|
bytes: []const u8 = "",
|
||||||
num_lit_suffix: NumLitSuffix = .None,
|
num_lit_suffix: NumLitSuffix = .None,
|
||||||
|
|
||||||
pub const Id = enum {
|
pub const Id = enum {
|
||||||
@ -17,20 +17,33 @@ pub const CToken = struct {
|
|||||||
NumLitInt,
|
NumLitInt,
|
||||||
NumLitFloat,
|
NumLitFloat,
|
||||||
Identifier,
|
Identifier,
|
||||||
|
Plus,
|
||||||
Minus,
|
Minus,
|
||||||
Slash,
|
Slash,
|
||||||
LParen,
|
LParen,
|
||||||
RParen,
|
RParen,
|
||||||
Eof,
|
Eof,
|
||||||
Dot,
|
Dot,
|
||||||
Asterisk,
|
Asterisk, // *
|
||||||
Bang,
|
Ampersand, // &
|
||||||
Tilde,
|
And, // &&
|
||||||
Shl,
|
Assign, // =
|
||||||
Lt,
|
Or, // ||
|
||||||
|
Bang, // !
|
||||||
|
Tilde, // ~
|
||||||
|
Shl, // <<
|
||||||
|
Shr, // >>
|
||||||
|
Lt, // <
|
||||||
|
Lte, // <=
|
||||||
|
Gt, // >
|
||||||
|
Gte, // >=
|
||||||
|
Eq, // ==
|
||||||
|
Ne, // !=
|
||||||
|
Increment, // ++
|
||||||
|
Decrement, // --
|
||||||
Comma,
|
Comma,
|
||||||
Fn,
|
Fn,
|
||||||
Arrow,
|
Arrow, // ->
|
||||||
LBrace,
|
LBrace,
|
||||||
RBrace,
|
RBrace,
|
||||||
Pipe,
|
Pipe,
|
||||||
@ -225,7 +238,14 @@ fn zigifyEscapeSequences(ctx: *Context, loc: ZigClangSourceLocation, name: []con
|
|||||||
fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:0]const u8, i: *usize) !CToken {
|
fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:0]const u8, i: *usize) !CToken {
|
||||||
var state: enum {
|
var state: enum {
|
||||||
Start,
|
Start,
|
||||||
GotLt,
|
SawLt,
|
||||||
|
SawGt,
|
||||||
|
SawPlus,
|
||||||
|
SawMinus,
|
||||||
|
SawAmpersand,
|
||||||
|
SawPipe,
|
||||||
|
SawBang,
|
||||||
|
SawEq,
|
||||||
CharLit,
|
CharLit,
|
||||||
OpenComment,
|
OpenComment,
|
||||||
Comment,
|
Comment,
|
||||||
@ -235,7 +255,7 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
|
|||||||
Identifier,
|
Identifier,
|
||||||
Decimal,
|
Decimal,
|
||||||
Octal,
|
Octal,
|
||||||
GotZero,
|
SawZero,
|
||||||
Hex,
|
Hex,
|
||||||
Bin,
|
Bin,
|
||||||
Float,
|
Float,
|
||||||
@ -246,7 +266,6 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
|
|||||||
NumLitIntSuffixL,
|
NumLitIntSuffixL,
|
||||||
NumLitIntSuffixLL,
|
NumLitIntSuffixLL,
|
||||||
NumLitIntSuffixUL,
|
NumLitIntSuffixUL,
|
||||||
Minus,
|
|
||||||
Done,
|
Done,
|
||||||
} = .Start;
|
} = .Start;
|
||||||
|
|
||||||
@ -267,7 +286,7 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
|
|||||||
.Hex,
|
.Hex,
|
||||||
.Bin,
|
.Bin,
|
||||||
.Octal,
|
.Octal,
|
||||||
.GotZero,
|
.SawZero,
|
||||||
.Float,
|
.Float,
|
||||||
.FloatExp,
|
.FloatExp,
|
||||||
=> {
|
=> {
|
||||||
@ -275,13 +294,19 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
|
|||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
.Start,
|
.Start,
|
||||||
.Minus,
|
.SawMinus,
|
||||||
.Done,
|
.Done,
|
||||||
.NumLitIntSuffixU,
|
.NumLitIntSuffixU,
|
||||||
.NumLitIntSuffixL,
|
.NumLitIntSuffixL,
|
||||||
.NumLitIntSuffixUL,
|
.NumLitIntSuffixUL,
|
||||||
.NumLitIntSuffixLL,
|
.NumLitIntSuffixLL,
|
||||||
.GotLt,
|
.SawLt,
|
||||||
|
.SawGt,
|
||||||
|
.SawPlus,
|
||||||
|
.SawAmpersand,
|
||||||
|
.SawPipe,
|
||||||
|
.SawBang,
|
||||||
|
.SawEq,
|
||||||
=> {
|
=> {
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
@ -333,7 +358,7 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
|
|||||||
begin_index = i.*;
|
begin_index = i.*;
|
||||||
},
|
},
|
||||||
'0' => {
|
'0' => {
|
||||||
state = .GotZero;
|
state = .SawZero;
|
||||||
result.id = .NumLitInt;
|
result.id = .NumLitInt;
|
||||||
begin_index = i.*;
|
begin_index = i.*;
|
||||||
},
|
},
|
||||||
@ -343,7 +368,11 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
|
|||||||
},
|
},
|
||||||
'<' => {
|
'<' => {
|
||||||
result.id = .Lt;
|
result.id = .Lt;
|
||||||
state = .GotLt;
|
state = .SawLt;
|
||||||
|
},
|
||||||
|
'>' => {
|
||||||
|
result.id = .Gt;
|
||||||
|
state = .SawGt;
|
||||||
},
|
},
|
||||||
'(' => {
|
'(' => {
|
||||||
result.id = .LParen;
|
result.id = .LParen;
|
||||||
@ -357,18 +386,26 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
|
|||||||
result.id = .Asterisk;
|
result.id = .Asterisk;
|
||||||
state = .Done;
|
state = .Done;
|
||||||
},
|
},
|
||||||
|
'+' => {
|
||||||
|
result.id = .Plus;
|
||||||
|
state = .SawPlus;
|
||||||
|
},
|
||||||
'-' => {
|
'-' => {
|
||||||
state = .Minus;
|
|
||||||
result.id = .Minus;
|
result.id = .Minus;
|
||||||
|
state = .SawMinus;
|
||||||
},
|
},
|
||||||
'!' => {
|
'!' => {
|
||||||
result.id = .Bang;
|
result.id = .Bang;
|
||||||
state = .Done;
|
state = .SawBang;
|
||||||
},
|
},
|
||||||
'~' => {
|
'~' => {
|
||||||
result.id = .Tilde;
|
result.id = .Tilde;
|
||||||
state = .Done;
|
state = .Done;
|
||||||
},
|
},
|
||||||
|
'=' => {
|
||||||
|
result.id = .Assign;
|
||||||
|
state = .SawEq;
|
||||||
|
},
|
||||||
',' => {
|
',' => {
|
||||||
result.id = .Comma;
|
result.id = .Comma;
|
||||||
state = .Done;
|
state = .Done;
|
||||||
@ -383,7 +420,11 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
|
|||||||
},
|
},
|
||||||
'|' => {
|
'|' => {
|
||||||
result.id = .Pipe;
|
result.id = .Pipe;
|
||||||
state = .Done;
|
state = .SawPipe;
|
||||||
|
},
|
||||||
|
'&' => {
|
||||||
|
result.id = .Ampersand;
|
||||||
|
state = .SawAmpersand;
|
||||||
},
|
},
|
||||||
'?' => {
|
'?' => {
|
||||||
result.id = .QuestionMark;
|
result.id = .QuestionMark;
|
||||||
@ -400,26 +441,88 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.Done => return result,
|
.Done => return result,
|
||||||
.Minus => {
|
.SawMinus => {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
'>' => {
|
'>' => {
|
||||||
result.id = .Arrow;
|
result.id = .Arrow;
|
||||||
state = .Done;
|
state = .Done;
|
||||||
},
|
},
|
||||||
else => {
|
'-' => {
|
||||||
return result;
|
result.id = .Decrement;
|
||||||
|
state = .Done;
|
||||||
},
|
},
|
||||||
|
else => return result,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.GotLt => {
|
.SawPlus => {
|
||||||
|
switch (c) {
|
||||||
|
'+' => {
|
||||||
|
result.id = .Increment;
|
||||||
|
state = .Done;
|
||||||
|
},
|
||||||
|
else => return result,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.SawLt => {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
'<' => {
|
'<' => {
|
||||||
result.id = .Shl;
|
result.id = .Shl;
|
||||||
state = .Done;
|
state = .Done;
|
||||||
},
|
},
|
||||||
else => {
|
'=' => {
|
||||||
return result;
|
result.id = .Lte;
|
||||||
|
state = .Done;
|
||||||
},
|
},
|
||||||
|
else => return result,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.SawGt => {
|
||||||
|
switch (c) {
|
||||||
|
'>' => {
|
||||||
|
result.id = .Shr;
|
||||||
|
state = .Done;
|
||||||
|
},
|
||||||
|
'=' => {
|
||||||
|
result.id = .Gte;
|
||||||
|
state = .Done;
|
||||||
|
},
|
||||||
|
else => return result,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.SawPipe => {
|
||||||
|
switch (c) {
|
||||||
|
'|' => {
|
||||||
|
result.id = .Or;
|
||||||
|
state = .Done;
|
||||||
|
},
|
||||||
|
else => return result,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.SawAmpersand => {
|
||||||
|
switch (c) {
|
||||||
|
'&' => {
|
||||||
|
result.id = .And;
|
||||||
|
state = .Done;
|
||||||
|
},
|
||||||
|
else => return result,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.SawBang => {
|
||||||
|
switch (c) {
|
||||||
|
'=' => {
|
||||||
|
result.id = .Ne;
|
||||||
|
state = .Done;
|
||||||
|
},
|
||||||
|
else => return result,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.SawEq => {
|
||||||
|
switch (c) {
|
||||||
|
'=' => {
|
||||||
|
result.id = .Eq;
|
||||||
|
state = .Done;
|
||||||
|
},
|
||||||
|
else => return result,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.Float => {
|
.Float => {
|
||||||
@ -454,7 +557,7 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
|
|||||||
'0'...'9' => {
|
'0'...'9' => {
|
||||||
state = .FloatExp;
|
state = .FloatExp;
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
try failDecl(ctx, loc, name, "macro tokenizing failed: expected a digit or '+' or '-'", .{});
|
try failDecl(ctx, loc, name, "macro tokenizing failed: expected a digit or '+' or '-'", .{});
|
||||||
return error.TokenizingFailed;
|
return error.TokenizingFailed;
|
||||||
},
|
},
|
||||||
@ -514,7 +617,7 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.GotZero => {
|
.SawZero => {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
'x', 'X' => {
|
'x', 'X' => {
|
||||||
state = .Hex;
|
state = .Hex;
|
||||||
@ -726,76 +829,114 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
|
|||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expectTokens(tl: *TokenList, src: [*:0]const u8, expected: []CToken) void {
|
||||||
|
// these can be undefined since they are only used for error reporting
|
||||||
|
tokenizeCMacro(undefined, undefined, undefined, tl, src) catch unreachable;
|
||||||
|
var it = tl.iterator(0);
|
||||||
|
for (expected) |t| {
|
||||||
|
var tok = it.next().?;
|
||||||
|
std.testing.expectEqual(t.id, tok.id);
|
||||||
|
if (t.bytes.len > 0) {
|
||||||
|
//std.debug.warn(" {} = {}\n", .{tok.bytes, t.bytes});
|
||||||
|
std.testing.expectEqualSlices(u8, tok.bytes, t.bytes);
|
||||||
|
}
|
||||||
|
if (t.num_lit_suffix != .None) {
|
||||||
|
std.testing.expectEqual(t.num_lit_suffix, tok.num_lit_suffix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std.testing.expect(it.next() == null);
|
||||||
|
tl.shrink(0);
|
||||||
|
}
|
||||||
|
|
||||||
test "tokenize macro" {
|
test "tokenize macro" {
|
||||||
var tl = TokenList.init(std.heap.page_allocator);
|
var tl = TokenList.init(std.heap.page_allocator);
|
||||||
defer tl.deinit();
|
defer tl.deinit();
|
||||||
|
|
||||||
const src = "TEST(0\n";
|
expectTokens(&tl, "TEST(0\n", &[_]CToken{
|
||||||
try tokenizeCMacro(&tl, src);
|
.{ .id = .Identifier, .bytes = "TEST" },
|
||||||
var it = tl.iterator(0);
|
.{ .id = .Fn },
|
||||||
expect(it.next().?.id == .Identifier);
|
.{ .id = .LParen },
|
||||||
expect(it.next().?.id == .Fn);
|
.{ .id = .NumLitInt, .bytes = "0" },
|
||||||
expect(it.next().?.id == .LParen);
|
.{ .id = .Eof },
|
||||||
expect(std.mem.eql(u8, it.next().?.bytes, "0"));
|
});
|
||||||
expect(it.next().?.id == .Eof);
|
|
||||||
expect(it.next() == null);
|
|
||||||
tl.shrink(0);
|
|
||||||
|
|
||||||
const src2 = "__FLT_MIN_10_EXP__ -37\n";
|
expectTokens(&tl, "__FLT_MIN_10_EXP__ -37\n", &[_]CToken{
|
||||||
try tokenizeCMacro(&tl, src2);
|
.{ .id = .Identifier, .bytes = "__FLT_MIN_10_EXP__" },
|
||||||
it = tl.iterator(0);
|
.{ .id = .Minus },
|
||||||
expect(std.mem.eql(u8, it.next().?.bytes, "__FLT_MIN_10_EXP__"));
|
.{ .id = .NumLitInt, .bytes = "37" },
|
||||||
expect(it.next().?.id == .Minus);
|
.{ .id = .Eof },
|
||||||
expect(std.mem.eql(u8, it.next().?.bytes, "37"));
|
});
|
||||||
expect(it.next().?.id == .Eof);
|
|
||||||
expect(it.next() == null);
|
|
||||||
tl.shrink(0);
|
|
||||||
|
|
||||||
const src3 = "__llvm__ 1\n#define";
|
expectTokens(&tl, "__llvm__ 1\n#define", &[_]CToken{
|
||||||
try tokenizeCMacro(&tl, src3);
|
.{ .id = .Identifier, .bytes = "__llvm__" },
|
||||||
it = tl.iterator(0);
|
.{ .id = .NumLitInt, .bytes = "1" },
|
||||||
expect(std.mem.eql(u8, it.next().?.bytes, "__llvm__"));
|
.{ .id = .Eof },
|
||||||
expect(std.mem.eql(u8, it.next().?.bytes, "1"));
|
});
|
||||||
expect(it.next().?.id == .Eof);
|
|
||||||
expect(it.next() == null);
|
|
||||||
tl.shrink(0);
|
|
||||||
|
|
||||||
const src4 = "TEST 2";
|
expectTokens(&tl, "TEST 2", &[_]CToken{
|
||||||
try tokenizeCMacro(&tl, src4);
|
.{ .id = .Identifier, .bytes = "TEST" },
|
||||||
it = tl.iterator(0);
|
.{ .id = .NumLitInt, .bytes = "2" },
|
||||||
expect(it.next().?.id == .Identifier);
|
.{ .id = .Eof },
|
||||||
expect(std.mem.eql(u8, it.next().?.bytes, "2"));
|
});
|
||||||
expect(it.next().?.id == .Eof);
|
|
||||||
expect(it.next() == null);
|
|
||||||
tl.shrink(0);
|
|
||||||
|
|
||||||
const src5 = "FOO 0ull";
|
expectTokens(&tl, "FOO 0ull", &[_]CToken{
|
||||||
try tokenizeCMacro(&tl, src5);
|
.{ .id = .Identifier, .bytes = "FOO" },
|
||||||
it = tl.iterator(0);
|
.{ .id = .NumLitInt, .bytes = "0", .num_lit_suffix = .LLU },
|
||||||
expect(it.next().?.id == .Identifier);
|
.{ .id = .Eof },
|
||||||
expect(std.mem.eql(u8, it.next().?.bytes, "0"));
|
});
|
||||||
expect(it.next().?.id == .Eof);
|
}
|
||||||
expect(it.next() == null);
|
|
||||||
tl.shrink(0);
|
test "tokenize macro ops" {
|
||||||
|
var tl = TokenList.init(std.heap.page_allocator);
|
||||||
|
defer tl.deinit();
|
||||||
|
|
||||||
|
expectTokens(&tl, "ADD A + B", &[_]CToken{
|
||||||
|
.{ .id = .Identifier, .bytes = "ADD" },
|
||||||
|
.{ .id = .Identifier, .bytes = "A" },
|
||||||
|
.{ .id = .Plus },
|
||||||
|
.{ .id = .Identifier, .bytes = "B" },
|
||||||
|
.{ .id = .Eof },
|
||||||
|
});
|
||||||
|
|
||||||
|
expectTokens(&tl, "ADD (A) + B", &[_]CToken{
|
||||||
|
.{ .id = .Identifier, .bytes = "ADD" },
|
||||||
|
.{ .id = .LParen },
|
||||||
|
.{ .id = .Identifier, .bytes = "A" },
|
||||||
|
.{ .id = .RParen },
|
||||||
|
.{ .id = .Plus },
|
||||||
|
.{ .id = .Identifier, .bytes = "B" },
|
||||||
|
.{ .id = .Eof },
|
||||||
|
});
|
||||||
|
|
||||||
|
expectTokens(&tl, "ADD (A) + B", &[_]CToken{
|
||||||
|
.{ .id = .Identifier, .bytes = "ADD" },
|
||||||
|
.{ .id = .LParen },
|
||||||
|
.{ .id = .Identifier, .bytes = "A" },
|
||||||
|
.{ .id = .RParen },
|
||||||
|
.{ .id = .Plus },
|
||||||
|
.{ .id = .Identifier, .bytes = "B" },
|
||||||
|
.{ .id = .Eof },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
test "escape sequences" {
|
test "escape sequences" {
|
||||||
var buf: [1024]u8 = undefined;
|
var buf: [1024]u8 = undefined;
|
||||||
var alloc = std.heap.FixedBufferAllocator.init(buf[0..]);
|
var alloc = std.heap.FixedBufferAllocator.init(buf[0..]);
|
||||||
const a = &alloc.allocator;
|
const a = &alloc.allocator;
|
||||||
expect(std.mem.eql(u8, (try zigifyEscapeSequences(a, .{
|
// these can be undefined since they are only used for error reporting
|
||||||
|
expect(std.mem.eql(u8, (try zigifyEscapeSequences(undefined, undefined, undefined, a, .{
|
||||||
.id = .StrLit,
|
.id = .StrLit,
|
||||||
.bytes = "\\x0077",
|
.bytes = "\\x0077",
|
||||||
})).bytes, "\\x77"));
|
})).bytes, "\\x77"));
|
||||||
expect(std.mem.eql(u8, (try zigifyEscapeSequences(a, .{
|
expect(std.mem.eql(u8, (try zigifyEscapeSequences(undefined, undefined, undefined, a, .{
|
||||||
.id = .StrLit,
|
.id = .StrLit,
|
||||||
.bytes = "\\24500",
|
.bytes = "\\24500",
|
||||||
})).bytes, "\\xa500"));
|
})).bytes, "\\xa500"));
|
||||||
expect(std.mem.eql(u8, (try zigifyEscapeSequences(a, .{
|
expect(std.mem.eql(u8, (try zigifyEscapeSequences(undefined, undefined, undefined, a, .{
|
||||||
.id = .StrLit,
|
.id = .StrLit,
|
||||||
.bytes = "\\x0077 abc",
|
.bytes = "\\x0077 abc",
|
||||||
})).bytes, "\\x77 abc"));
|
})).bytes, "\\x77 abc"));
|
||||||
expect(std.mem.eql(u8, (try zigifyEscapeSequences(a, .{
|
expect(std.mem.eql(u8, (try zigifyEscapeSequences(undefined, undefined, undefined, a, .{
|
||||||
.id = .StrLit,
|
.id = .StrLit,
|
||||||
.bytes = "\\045abc",
|
.bytes = "\\045abc",
|
||||||
})).bytes, "\\x25abc"));
|
})).bytes, "\\x25abc"));
|
||||||
|
@ -43,6 +43,7 @@ pub const struct_ZigClangImplicitCastExpr = @OpaqueType();
|
|||||||
pub const struct_ZigClangIncompleteArrayType = @OpaqueType();
|
pub const struct_ZigClangIncompleteArrayType = @OpaqueType();
|
||||||
pub const struct_ZigClangIntegerLiteral = @OpaqueType();
|
pub const struct_ZigClangIntegerLiteral = @OpaqueType();
|
||||||
pub const struct_ZigClangMacroDefinitionRecord = @OpaqueType();
|
pub const struct_ZigClangMacroDefinitionRecord = @OpaqueType();
|
||||||
|
pub const struct_ZigClangMacroExpansion = @OpaqueType();
|
||||||
pub const struct_ZigClangMacroQualifiedType = @OpaqueType();
|
pub const struct_ZigClangMacroQualifiedType = @OpaqueType();
|
||||||
pub const struct_ZigClangMemberExpr = @OpaqueType();
|
pub const struct_ZigClangMemberExpr = @OpaqueType();
|
||||||
pub const struct_ZigClangNamedDecl = @OpaqueType();
|
pub const struct_ZigClangNamedDecl = @OpaqueType();
|
||||||
@ -803,8 +804,8 @@ pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *cons
|
|||||||
pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
|
pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
|
||||||
pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;
|
pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;
|
||||||
pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
|
pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
|
||||||
pub extern fn ZigClangExpr_getStmtClass(self: ?*const struct_ZigClangExpr) ZigClangStmtClass;
|
pub extern fn ZigClangExpr_getStmtClass(self: *const struct_ZigClangExpr) ZigClangStmtClass;
|
||||||
pub extern fn ZigClangExpr_getType(self: ?*const struct_ZigClangExpr) struct_ZigClangQualType;
|
pub extern fn ZigClangExpr_getType(self: *const struct_ZigClangExpr) struct_ZigClangQualType;
|
||||||
pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
|
pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
|
||||||
pub extern fn ZigClangInitListExpr_getInit(self: ?*const struct_ZigClangInitListExpr, i: c_uint) *const ZigClangExpr;
|
pub extern fn ZigClangInitListExpr_getInit(self: ?*const struct_ZigClangInitListExpr, i: c_uint) *const ZigClangExpr;
|
||||||
pub extern fn ZigClangInitListExpr_getArrayFiller(self: ?*const struct_ZigClangInitListExpr) *const ZigClangExpr;
|
pub extern fn ZigClangInitListExpr_getArrayFiller(self: ?*const struct_ZigClangInitListExpr) *const ZigClangExpr;
|
||||||
@ -831,6 +832,8 @@ pub extern fn ZigClangFunctionDecl_hasBody(self: *const ZigClangFunctionDecl) bo
|
|||||||
pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const ZigClangFunctionDecl) ZigClangStorageClass;
|
pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const ZigClangFunctionDecl) ZigClangStorageClass;
|
||||||
pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDecl, i: c_uint) *const struct_ZigClangParmVarDecl;
|
pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDecl, i: c_uint) *const struct_ZigClangParmVarDecl;
|
||||||
pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const struct_ZigClangStmt;
|
pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const struct_ZigClangStmt;
|
||||||
|
pub extern fn ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(self: *const ZigClangFunctionDecl) bool;
|
||||||
|
pub extern fn ZigClangFunctionDecl_isInlineSpecified(self: *const ZigClangFunctionDecl) bool;
|
||||||
|
|
||||||
pub extern fn ZigClangBuiltinType_getKind(self: *const struct_ZigClangBuiltinType) ZigClangBuiltinTypeKind;
|
pub extern fn ZigClangBuiltinType_getKind(self: *const struct_ZigClangBuiltinType) ZigClangBuiltinTypeKind;
|
||||||
|
|
||||||
@ -889,6 +892,7 @@ pub const ZigClangImplicitCastExpr = struct_ZigClangImplicitCastExpr;
|
|||||||
pub const ZigClangIncompleteArrayType = struct_ZigClangIncompleteArrayType;
|
pub const ZigClangIncompleteArrayType = struct_ZigClangIncompleteArrayType;
|
||||||
pub const ZigClangIntegerLiteral = struct_ZigClangIntegerLiteral;
|
pub const ZigClangIntegerLiteral = struct_ZigClangIntegerLiteral;
|
||||||
pub const ZigClangMacroDefinitionRecord = struct_ZigClangMacroDefinitionRecord;
|
pub const ZigClangMacroDefinitionRecord = struct_ZigClangMacroDefinitionRecord;
|
||||||
|
pub const ZigClangMacroExpansion = struct_ZigClangMacroExpansion;
|
||||||
pub const ZigClangMacroQualifiedType = struct_ZigClangMacroQualifiedType;
|
pub const ZigClangMacroQualifiedType = struct_ZigClangMacroQualifiedType;
|
||||||
pub const ZigClangMemberExpr = struct_ZigClangMemberExpr;
|
pub const ZigClangMemberExpr = struct_ZigClangMemberExpr;
|
||||||
pub const ZigClangNamedDecl = struct_ZigClangNamedDecl;
|
pub const ZigClangNamedDecl = struct_ZigClangNamedDecl;
|
||||||
@ -1058,6 +1062,8 @@ pub extern fn ZigClangMacroDefinitionRecord_getName_getNameStart(*const ZigClang
|
|||||||
pub extern fn ZigClangMacroDefinitionRecord_getSourceRange_getBegin(*const ZigClangMacroDefinitionRecord) ZigClangSourceLocation;
|
pub extern fn ZigClangMacroDefinitionRecord_getSourceRange_getBegin(*const ZigClangMacroDefinitionRecord) ZigClangSourceLocation;
|
||||||
pub extern fn ZigClangMacroDefinitionRecord_getSourceRange_getEnd(*const ZigClangMacroDefinitionRecord) ZigClangSourceLocation;
|
pub extern fn ZigClangMacroDefinitionRecord_getSourceRange_getEnd(*const ZigClangMacroDefinitionRecord) ZigClangSourceLocation;
|
||||||
|
|
||||||
|
pub extern fn ZigClangMacroExpansion_getDefinition(*const ZigClangMacroExpansion) *const ZigClangMacroDefinitionRecord;
|
||||||
|
|
||||||
pub extern fn ZigClangIfStmt_getThen(*const ZigClangIfStmt) *const ZigClangStmt;
|
pub extern fn ZigClangIfStmt_getThen(*const ZigClangIfStmt) *const ZigClangStmt;
|
||||||
pub extern fn ZigClangIfStmt_getElse(*const ZigClangIfStmt) ?*const ZigClangStmt;
|
pub extern fn ZigClangIfStmt_getElse(*const ZigClangIfStmt) ?*const ZigClangStmt;
|
||||||
pub extern fn ZigClangIfStmt_getCond(*const ZigClangIfStmt) *const ZigClangStmt;
|
pub extern fn ZigClangIfStmt_getCond(*const ZigClangIfStmt) *const ZigClangStmt;
|
||||||
|
@ -119,11 +119,11 @@ fn linkDiagCallbackErrorable(ctx: *Context, msg: []const u8) !void {
|
|||||||
|
|
||||||
fn toExternObjectFormatType(ofmt: ObjectFormat) c.ZigLLVM_ObjectFormatType {
|
fn toExternObjectFormatType(ofmt: ObjectFormat) c.ZigLLVM_ObjectFormatType {
|
||||||
return switch (ofmt) {
|
return switch (ofmt) {
|
||||||
.unknown => c.ZigLLVM_UnknownObjectFormat,
|
.unknown => .ZigLLVM_UnknownObjectFormat,
|
||||||
.coff => c.ZigLLVM_COFF,
|
.coff => .ZigLLVM_COFF,
|
||||||
.elf => c.ZigLLVM_ELF,
|
.elf => .ZigLLVM_ELF,
|
||||||
.macho => c.ZigLLVM_MachO,
|
.macho => .ZigLLVM_MachO,
|
||||||
.wasm => c.ZigLLVM_Wasm,
|
.wasm => .ZigLLVM_Wasm,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,24 +226,24 @@ pub const PrintMessageAction = VerifierFailureAction.LLVMPrintMessageAction;
|
|||||||
pub const ReturnStatusAction = VerifierFailureAction.LLVMReturnStatusAction;
|
pub const ReturnStatusAction = VerifierFailureAction.LLVMReturnStatusAction;
|
||||||
pub const VerifierFailureAction = c.LLVMVerifierFailureAction;
|
pub const VerifierFailureAction = c.LLVMVerifierFailureAction;
|
||||||
|
|
||||||
pub const CodeGenLevelNone = c.LLVMCodeGenOptLevel.LLVMCodeGenLevelNone;
|
pub const CodeGenLevelNone = CodeGenOptLevel.LLVMCodeGenLevelNone;
|
||||||
pub const CodeGenLevelLess = c.LLVMCodeGenOptLevel.LLVMCodeGenLevelLess;
|
pub const CodeGenLevelLess = CodeGenOptLevel.LLVMCodeGenLevelLess;
|
||||||
pub const CodeGenLevelDefault = c.LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault;
|
pub const CodeGenLevelDefault = CodeGenOptLevel.LLVMCodeGenLevelDefault;
|
||||||
pub const CodeGenLevelAggressive = c.LLVMCodeGenOptLevel.LLVMCodeGenLevelAggressive;
|
pub const CodeGenLevelAggressive = CodeGenOptLevel.LLVMCodeGenLevelAggressive;
|
||||||
pub const CodeGenOptLevel = c.LLVMCodeGenOptLevel;
|
pub const CodeGenOptLevel = c.LLVMCodeGenOptLevel;
|
||||||
|
|
||||||
pub const RelocDefault = c.LLVMRelocMode.LLVMRelocDefault;
|
pub const RelocDefault = RelocMode.LLVMRelocDefault;
|
||||||
pub const RelocStatic = c.LLVMRelocMode.LLVMRelocStatic;
|
pub const RelocStatic = RelocMode.LLVMRelocStatic;
|
||||||
pub const RelocPIC = c.LLVMRelocMode.LLVMRelocPIC;
|
pub const RelocPIC = RelocMode.LLVMRelocPIC;
|
||||||
pub const RelocDynamicNoPic = c.LLVMRelocMode.LLVMRelocDynamicNoPic;
|
pub const RelocDynamicNoPic = RelocMode.LLVMRelocDynamicNoPic;
|
||||||
pub const RelocMode = c.LLVMRelocMode;
|
pub const RelocMode = c.LLVMRelocMode;
|
||||||
|
|
||||||
pub const CodeModelDefault = c.LLVMCodeModel.LLVMCodeModelDefault;
|
pub const CodeModelDefault = CodeModel.LLVMCodeModelDefault;
|
||||||
pub const CodeModelJITDefault = c.LLVMCodeModel.LLVMCodeModelJITDefault;
|
pub const CodeModelJITDefault = CodeModel.LLVMCodeModelJITDefault;
|
||||||
pub const CodeModelSmall = c.LLVMCodeModel.LLVMCodeModelSmall;
|
pub const CodeModelSmall = CodeModel.LLVMCodeModelSmall;
|
||||||
pub const CodeModelKernel = c.LLVMCodeModel.LLVMCodeModelKernel;
|
pub const CodeModelKernel = CodeModel.LLVMCodeModelKernel;
|
||||||
pub const CodeModelMedium = c.LLVMCodeModel.LLVMCodeModelMedium;
|
pub const CodeModelMedium = CodeModel.LLVMCodeModelMedium;
|
||||||
pub const CodeModelLarge = c.LLVMCodeModel.LLVMCodeModelLarge;
|
pub const CodeModelLarge = CodeModel.LLVMCodeModelLarge;
|
||||||
pub const CodeModel = c.LLVMCodeModel;
|
pub const CodeModel = c.LLVMCodeModel;
|
||||||
|
|
||||||
pub const EmitAssembly = EmitOutputType.ZigLLVM_EmitAssembly;
|
pub const EmitAssembly = EmitOutputType.ZigLLVM_EmitAssembly;
|
||||||
@ -251,13 +251,13 @@ pub const EmitBinary = EmitOutputType.ZigLLVM_EmitBinary;
|
|||||||
pub const EmitLLVMIr = EmitOutputType.ZigLLVM_EmitLLVMIr;
|
pub const EmitLLVMIr = EmitOutputType.ZigLLVM_EmitLLVMIr;
|
||||||
pub const EmitOutputType = c.ZigLLVM_EmitOutputType;
|
pub const EmitOutputType = c.ZigLLVM_EmitOutputType;
|
||||||
|
|
||||||
pub const CCallConv = c.LLVMCCallConv;
|
pub const CCallConv = CallConv.LLVMCCallConv;
|
||||||
pub const FastCallConv = c.LLVMFastCallConv;
|
pub const FastCallConv = CallConv.LLVMFastCallConv;
|
||||||
pub const ColdCallConv = c.LLVMColdCallConv;
|
pub const ColdCallConv = CallConv.LLVMColdCallConv;
|
||||||
pub const WebKitJSCallConv = c.LLVMWebKitJSCallConv;
|
pub const WebKitJSCallConv = CallConv.LLVMWebKitJSCallConv;
|
||||||
pub const AnyRegCallConv = c.LLVMAnyRegCallConv;
|
pub const AnyRegCallConv = CallConv.LLVMAnyRegCallConv;
|
||||||
pub const X86StdcallCallConv = c.LLVMX86StdcallCallConv;
|
pub const X86StdcallCallConv = CallConv.LLVMX86StdcallCallConv;
|
||||||
pub const X86FastcallCallConv = c.LLVMX86FastcallCallConv;
|
pub const X86FastcallCallConv = CallConv.LLVMX86FastcallCallConv;
|
||||||
pub const CallConv = c.LLVMCallConv;
|
pub const CallConv = c.LLVMCallConv;
|
||||||
|
|
||||||
pub const CallAttr = extern enum {
|
pub const CallAttr = extern enum {
|
||||||
@ -288,6 +288,6 @@ extern fn ZigLLVMTargetMachineEmitToFile(
|
|||||||
) bool;
|
) bool;
|
||||||
|
|
||||||
pub const BuildCall = ZigLLVMBuildCall;
|
pub const BuildCall = ZigLLVMBuildCall;
|
||||||
extern fn ZigLLVMBuildCall(B: *Builder, Fn: *Value, Args: [*]*Value, NumArgs: c_uint, CC: c_uint, fn_inline: CallAttr, Name: [*:0]const u8) ?*Value;
|
extern fn ZigLLVMBuildCall(B: *Builder, Fn: *Value, Args: [*]*Value, NumArgs: c_uint, CC: CallConv, fn_inline: CallAttr, Name: [*:0]const u8) ?*Value;
|
||||||
|
|
||||||
pub const PrivateLinkage = c.LLVMLinkage.LLVMPrivateLinkage;
|
pub const PrivateLinkage = c.LLVMLinkage.LLVMPrivateLinkage;
|
||||||
|
@ -95,7 +95,7 @@ export fn stage2_translate_c(
|
|||||||
args_end: [*]?[*]const u8,
|
args_end: [*]?[*]const u8,
|
||||||
resources_path: [*:0]const u8,
|
resources_path: [*:0]const u8,
|
||||||
) Error {
|
) Error {
|
||||||
var errors: []translate_c.ClangErrMsg = undefined;
|
var errors = @as([*]translate_c.ClangErrMsg, undefined)[0..0];
|
||||||
out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {
|
out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {
|
||||||
error.SemanticAnalyzeFail => {
|
error.SemanticAnalyzeFail => {
|
||||||
out_errors_ptr.* = errors.ptr;
|
out_errors_ptr.* = errors.ptr;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,840 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2016 Andrew Kelley
|
|
||||||
*
|
|
||||||
* This file is part of zig, which is MIT licensed.
|
|
||||||
* See http://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "c_tokenizer.hpp"
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#define WHITESPACE_EXCEPT_N \
|
|
||||||
' ': \
|
|
||||||
case '\t': \
|
|
||||||
case '\v': \
|
|
||||||
case '\f'
|
|
||||||
|
|
||||||
#define DIGIT_NON_ZERO \
|
|
||||||
'1': \
|
|
||||||
case '2': \
|
|
||||||
case '3': \
|
|
||||||
case '4': \
|
|
||||||
case '5': \
|
|
||||||
case '6': \
|
|
||||||
case '7': \
|
|
||||||
case '8': \
|
|
||||||
case '9'
|
|
||||||
|
|
||||||
#define DIGIT \
|
|
||||||
'0': \
|
|
||||||
case DIGIT_NON_ZERO
|
|
||||||
|
|
||||||
#define ALPHA \
|
|
||||||
'a': \
|
|
||||||
case 'b': \
|
|
||||||
case 'c': \
|
|
||||||
case 'd': \
|
|
||||||
case 'e': \
|
|
||||||
case 'f': \
|
|
||||||
case 'g': \
|
|
||||||
case 'h': \
|
|
||||||
case 'i': \
|
|
||||||
case 'j': \
|
|
||||||
case 'k': \
|
|
||||||
case 'l': \
|
|
||||||
case 'm': \
|
|
||||||
case 'n': \
|
|
||||||
case 'o': \
|
|
||||||
case 'p': \
|
|
||||||
case 'q': \
|
|
||||||
case 'r': \
|
|
||||||
case 's': \
|
|
||||||
case 't': \
|
|
||||||
case 'u': \
|
|
||||||
case 'v': \
|
|
||||||
case 'w': \
|
|
||||||
case 'x': \
|
|
||||||
case 'y': \
|
|
||||||
case 'z': \
|
|
||||||
case 'A': \
|
|
||||||
case 'B': \
|
|
||||||
case 'C': \
|
|
||||||
case 'D': \
|
|
||||||
case 'E': \
|
|
||||||
case 'F': \
|
|
||||||
case 'G': \
|
|
||||||
case 'H': \
|
|
||||||
case 'I': \
|
|
||||||
case 'J': \
|
|
||||||
case 'K': \
|
|
||||||
case 'L': \
|
|
||||||
case 'M': \
|
|
||||||
case 'N': \
|
|
||||||
case 'O': \
|
|
||||||
case 'P': \
|
|
||||||
case 'Q': \
|
|
||||||
case 'R': \
|
|
||||||
case 'S': \
|
|
||||||
case 'T': \
|
|
||||||
case 'U': \
|
|
||||||
case 'V': \
|
|
||||||
case 'W': \
|
|
||||||
case 'X': \
|
|
||||||
case 'Y': \
|
|
||||||
case 'Z'
|
|
||||||
|
|
||||||
#define IDENT_START \
|
|
||||||
ALPHA: \
|
|
||||||
case '_'
|
|
||||||
|
|
||||||
#define IDENT \
|
|
||||||
IDENT_START: \
|
|
||||||
case DIGIT
|
|
||||||
|
|
||||||
#define LINE_ENDING \
|
|
||||||
'\r': \
|
|
||||||
case '\n'
|
|
||||||
|
|
||||||
static void begin_token(CTokenize *ctok, CTokId id) {
|
|
||||||
assert(ctok->cur_tok == nullptr);
|
|
||||||
ctok->tokens.add_one();
|
|
||||||
ctok->cur_tok = &ctok->tokens.last();
|
|
||||||
ctok->cur_tok->id = id;
|
|
||||||
|
|
||||||
switch (id) {
|
|
||||||
case CTokIdStrLit:
|
|
||||||
memset(&ctok->cur_tok->data.str_lit, 0, sizeof(Buf));
|
|
||||||
buf_resize(&ctok->cur_tok->data.str_lit, 0);
|
|
||||||
break;
|
|
||||||
case CTokIdSymbol:
|
|
||||||
memset(&ctok->cur_tok->data.symbol, 0, sizeof(Buf));
|
|
||||||
buf_resize(&ctok->cur_tok->data.symbol, 0);
|
|
||||||
break;
|
|
||||||
case CTokIdNumLitInt:
|
|
||||||
ctok->cur_tok->data.num_lit_int.x = 0;
|
|
||||||
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixNone;
|
|
||||||
break;
|
|
||||||
case CTokIdCharLit:
|
|
||||||
case CTokIdNumLitFloat:
|
|
||||||
case CTokIdMinus:
|
|
||||||
case CTokIdLParen:
|
|
||||||
case CTokIdRParen:
|
|
||||||
case CTokIdEOF:
|
|
||||||
case CTokIdDot:
|
|
||||||
case CTokIdAsterisk:
|
|
||||||
case CTokIdBang:
|
|
||||||
case CTokIdTilde:
|
|
||||||
case CTokIdShl:
|
|
||||||
case CTokIdLt:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void end_token(CTokenize *ctok) {
|
|
||||||
ctok->cur_tok = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mark_error(CTokenize *ctok) {
|
|
||||||
ctok->error = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_char(CTokenize *ctok, uint8_t c) {
|
|
||||||
assert(ctok->cur_tok);
|
|
||||||
if (ctok->cur_tok->id == CTokIdCharLit) {
|
|
||||||
ctok->cur_tok->data.char_lit = c;
|
|
||||||
ctok->state = CTokStateExpectEndQuot;
|
|
||||||
} else if (ctok->cur_tok->id == CTokIdStrLit) {
|
|
||||||
buf_append_char(&ctok->cur_tok->data.str_lit, c);
|
|
||||||
ctok->state = CTokStateString;
|
|
||||||
} else {
|
|
||||||
zig_unreachable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hex_digit(CTokenize *ctok, uint8_t value) {
|
|
||||||
// TODO @mul_with_overflow
|
|
||||||
ctok->cur_tok->data.num_lit_int.x *= 16;
|
|
||||||
// TODO @add_with_overflow
|
|
||||||
ctok->cur_tok->data.num_lit_int.x += value;
|
|
||||||
|
|
||||||
static const uint8_t hex_digit[] = "0123456789abcdef";
|
|
||||||
buf_append_char(&ctok->buf, hex_digit[value]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void end_float(CTokenize *ctok) {
|
|
||||||
// TODO detect errors, overflow, and underflow
|
|
||||||
double value = strtod(buf_ptr(&ctok->buf), nullptr);
|
|
||||||
|
|
||||||
ctok->cur_tok->data.num_lit_float = value;
|
|
||||||
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
|
|
||||||
ctok->tokens.resize(0);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
ctok->error = false;
|
|
||||||
ctok->cur_tok = nullptr;
|
|
||||||
|
|
||||||
buf_resize(&ctok->buf, 0);
|
|
||||||
|
|
||||||
for (; *c; c += 1) {
|
|
||||||
switch (ctok->state) {
|
|
||||||
case CTokStateStart:
|
|
||||||
switch (*c) {
|
|
||||||
case WHITESPACE_EXCEPT_N:
|
|
||||||
break;
|
|
||||||
case '\'':
|
|
||||||
ctok->state = CTokStateExpectChar;
|
|
||||||
begin_token(ctok, CTokIdCharLit);
|
|
||||||
break;
|
|
||||||
case '\"':
|
|
||||||
ctok->state = CTokStateString;
|
|
||||||
begin_token(ctok, CTokIdStrLit);
|
|
||||||
break;
|
|
||||||
case '/':
|
|
||||||
ctok->state = CTokStateOpenComment;
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
ctok->state = CTokStateBackslash;
|
|
||||||
break;
|
|
||||||
case LINE_ENDING:
|
|
||||||
goto found_end_of_macro;
|
|
||||||
case IDENT_START:
|
|
||||||
ctok->state = CTokStateIdentifier;
|
|
||||||
begin_token(ctok, CTokIdSymbol);
|
|
||||||
buf_append_char(&ctok->cur_tok->data.symbol, *c);
|
|
||||||
break;
|
|
||||||
case DIGIT_NON_ZERO:
|
|
||||||
ctok->state = CTokStateDecimal;
|
|
||||||
begin_token(ctok, CTokIdNumLitInt);
|
|
||||||
ctok->cur_tok->data.num_lit_int.x = *c - '0';
|
|
||||||
buf_resize(&ctok->buf, 0);
|
|
||||||
buf_append_char(&ctok->buf, *c);
|
|
||||||
break;
|
|
||||||
case '0':
|
|
||||||
ctok->state = CTokStateGotZero;
|
|
||||||
begin_token(ctok, CTokIdNumLitInt);
|
|
||||||
ctok->cur_tok->data.num_lit_int.x = 0;
|
|
||||||
buf_resize(&ctok->buf, 0);
|
|
||||||
buf_append_char(&ctok->buf, '0');
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
begin_token(ctok, CTokIdDot);
|
|
||||||
end_token(ctok);
|
|
||||||
break;
|
|
||||||
case '<':
|
|
||||||
begin_token(ctok, CTokIdLt);
|
|
||||||
ctok->state = CTokStateGotLt;
|
|
||||||
break;
|
|
||||||
case '(':
|
|
||||||
begin_token(ctok, CTokIdLParen);
|
|
||||||
end_token(ctok);
|
|
||||||
break;
|
|
||||||
case ')':
|
|
||||||
begin_token(ctok, CTokIdRParen);
|
|
||||||
end_token(ctok);
|
|
||||||
break;
|
|
||||||
case '*':
|
|
||||||
begin_token(ctok, CTokIdAsterisk);
|
|
||||||
end_token(ctok);
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
begin_token(ctok, CTokIdMinus);
|
|
||||||
end_token(ctok);
|
|
||||||
break;
|
|
||||||
case '!':
|
|
||||||
begin_token(ctok, CTokIdBang);
|
|
||||||
end_token(ctok);
|
|
||||||
break;
|
|
||||||
case '~':
|
|
||||||
begin_token(ctok, CTokIdTilde);
|
|
||||||
end_token(ctok);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return mark_error(ctok);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateGotLt:
|
|
||||||
switch (*c) {
|
|
||||||
case '<':
|
|
||||||
ctok->cur_tok->id = CTokIdShl;
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateFloat:
|
|
||||||
switch (*c) {
|
|
||||||
case '.':
|
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
case 'E':
|
|
||||||
buf_append_char(&ctok->buf, 'e');
|
|
||||||
ctok->state = CTokStateExpSign;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
case 'F':
|
|
||||||
case 'l':
|
|
||||||
case 'L':
|
|
||||||
end_float(ctok);
|
|
||||||
break;
|
|
||||||
case DIGIT:
|
|
||||||
buf_append_char(&ctok->buf, *c);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
end_float(ctok);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateExpSign:
|
|
||||||
switch (*c) {
|
|
||||||
case '+':
|
|
||||||
case '-':
|
|
||||||
ctok->state = CTokStateFloatExpFirst;
|
|
||||||
buf_append_char(&ctok->buf, *c);
|
|
||||||
break;
|
|
||||||
case DIGIT:
|
|
||||||
ctok->state = CTokStateFloatExp;
|
|
||||||
buf_append_char(&ctok->buf, *c);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return mark_error(ctok);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateFloatExpFirst:
|
|
||||||
switch (*c) {
|
|
||||||
case DIGIT:
|
|
||||||
buf_append_char(&ctok->buf, *c);
|
|
||||||
ctok->state = CTokStateFloatExp;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return mark_error(ctok);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateFloatExp:
|
|
||||||
switch (*c) {
|
|
||||||
case DIGIT:
|
|
||||||
buf_append_char(&ctok->buf, *c);
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
case 'F':
|
|
||||||
case 'l':
|
|
||||||
case 'L':
|
|
||||||
end_float(ctok);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
end_float(ctok);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateDecimal:
|
|
||||||
switch (*c) {
|
|
||||||
case DIGIT:
|
|
||||||
buf_append_char(&ctok->buf, *c);
|
|
||||||
|
|
||||||
// TODO @mul_with_overflow
|
|
||||||
ctok->cur_tok->data.num_lit_int.x *= 10;
|
|
||||||
// TODO @add_with_overflow
|
|
||||||
ctok->cur_tok->data.num_lit_int.x += *c - '0';
|
|
||||||
break;
|
|
||||||
case '\'':
|
|
||||||
break;
|
|
||||||
case 'u':
|
|
||||||
case 'U':
|
|
||||||
ctok->state = CTokStateNumLitIntSuffixU;
|
|
||||||
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixU;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
case 'L':
|
|
||||||
ctok->state = CTokStateNumLitIntSuffixL;
|
|
||||||
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixL;
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
buf_append_char(&ctok->buf, '.');
|
|
||||||
ctok->cur_tok->id = CTokIdNumLitFloat;
|
|
||||||
ctok->state = CTokStateFloat;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateGotZero:
|
|
||||||
switch (*c) {
|
|
||||||
case 'x':
|
|
||||||
case 'X':
|
|
||||||
ctok->state = CTokStateHex;
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
ctok->state = CTokStateFloat;
|
|
||||||
ctok->cur_tok->id = CTokIdNumLitFloat;
|
|
||||||
buf_append_char(&ctok->buf, '.');
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
case 'L':
|
|
||||||
case 'u':
|
|
||||||
case 'U':
|
|
||||||
c -= 1;
|
|
||||||
ctok->state = CTokStateDecimal;
|
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
ctok->state = CTokStateOctal;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateOctal:
|
|
||||||
switch (*c) {
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
// TODO @mul_with_overflow
|
|
||||||
ctok->cur_tok->data.num_lit_int.x *= 8;
|
|
||||||
// TODO @add_with_overflow
|
|
||||||
ctok->cur_tok->data.num_lit_int.x += *c - '0';
|
|
||||||
break;
|
|
||||||
case '8':
|
|
||||||
case '9':
|
|
||||||
return mark_error(ctok);
|
|
||||||
case '\'':
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateHex:
|
|
||||||
switch (*c) {
|
|
||||||
case '0':
|
|
||||||
hex_digit(ctok, 0);
|
|
||||||
break;
|
|
||||||
case '1':
|
|
||||||
hex_digit(ctok, 1);
|
|
||||||
break;
|
|
||||||
case '2':
|
|
||||||
hex_digit(ctok, 2);
|
|
||||||
break;
|
|
||||||
case '3':
|
|
||||||
hex_digit(ctok, 3);
|
|
||||||
break;
|
|
||||||
case '4':
|
|
||||||
hex_digit(ctok, 4);
|
|
||||||
break;
|
|
||||||
case '5':
|
|
||||||
hex_digit(ctok, 5);
|
|
||||||
break;
|
|
||||||
case '6':
|
|
||||||
hex_digit(ctok, 6);
|
|
||||||
break;
|
|
||||||
case '7':
|
|
||||||
hex_digit(ctok, 7);
|
|
||||||
break;
|
|
||||||
case '8':
|
|
||||||
hex_digit(ctok, 8);
|
|
||||||
break;
|
|
||||||
case '9':
|
|
||||||
hex_digit(ctok, 9);
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
case 'A':
|
|
||||||
hex_digit(ctok, 10);
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
case 'B':
|
|
||||||
hex_digit(ctok, 11);
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
case 'C':
|
|
||||||
hex_digit(ctok, 12);
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
case 'D':
|
|
||||||
hex_digit(ctok, 13);
|
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
case 'E':
|
|
||||||
hex_digit(ctok, 14);
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
case 'F':
|
|
||||||
hex_digit(ctok, 15);
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
case 'P':
|
|
||||||
ctok->cur_tok->id = CTokIdNumLitFloat;
|
|
||||||
ctok->state = CTokStateExpSign;
|
|
||||||
break;
|
|
||||||
case 'u':
|
|
||||||
case 'U':
|
|
||||||
// marks the number literal as unsigned
|
|
||||||
ctok->state = CTokStateNumLitIntSuffixU;
|
|
||||||
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixU;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
case 'L':
|
|
||||||
// marks the number literal as long
|
|
||||||
ctok->state = CTokStateNumLitIntSuffixL;
|
|
||||||
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateNumLitIntSuffixU:
|
|
||||||
switch (*c) {
|
|
||||||
case 'l':
|
|
||||||
case 'L':
|
|
||||||
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLU;
|
|
||||||
ctok->state = CTokStateNumLitIntSuffixUL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateNumLitIntSuffixL:
|
|
||||||
switch (*c) {
|
|
||||||
case 'l':
|
|
||||||
case 'L':
|
|
||||||
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLL;
|
|
||||||
ctok->state = CTokStateNumLitIntSuffixLL;
|
|
||||||
break;
|
|
||||||
case 'u':
|
|
||||||
case 'U':
|
|
||||||
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLU;
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateNumLitIntSuffixLL:
|
|
||||||
switch (*c) {
|
|
||||||
case 'u':
|
|
||||||
case 'U':
|
|
||||||
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLLU;
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateNumLitIntSuffixUL:
|
|
||||||
switch (*c) {
|
|
||||||
case 'l':
|
|
||||||
case 'L':
|
|
||||||
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLLU;
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateIdentifier:
|
|
||||||
switch (*c) {
|
|
||||||
case IDENT:
|
|
||||||
buf_append_char(&ctok->cur_tok->data.symbol, *c);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateString:
|
|
||||||
switch (*c) {
|
|
||||||
case '\\':
|
|
||||||
ctok->state = CTokStateCharEscape;
|
|
||||||
break;
|
|
||||||
case '\"':
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
buf_append_char(&ctok->cur_tok->data.str_lit, *c);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateExpectChar:
|
|
||||||
switch (*c) {
|
|
||||||
case '\\':
|
|
||||||
ctok->state = CTokStateCharEscape;
|
|
||||||
break;
|
|
||||||
case '\'':
|
|
||||||
return mark_error(ctok);
|
|
||||||
default:
|
|
||||||
ctok->cur_tok->data.char_lit = *c;
|
|
||||||
ctok->state = CTokStateExpectEndQuot;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateCharEscape:
|
|
||||||
switch (*c) {
|
|
||||||
case '\'':
|
|
||||||
case '"':
|
|
||||||
case '?':
|
|
||||||
case '\\':
|
|
||||||
add_char(ctok, *c);
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
add_char(ctok, '\a');
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
add_char(ctok, '\b');
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
add_char(ctok, '\f');
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
add_char(ctok, '\n');
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
add_char(ctok, '\r');
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
add_char(ctok, '\t');
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
add_char(ctok, '\v');
|
|
||||||
break;
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
ctok->state = CTokStateStrOctal;
|
|
||||||
ctok->cur_char = (uint8_t)(*c - '0');
|
|
||||||
ctok->octal_index = 1;
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
ctok->state = CTokStateStrHex;
|
|
||||||
ctok->cur_char = 0;
|
|
||||||
break;
|
|
||||||
case 'u':
|
|
||||||
zig_panic("TODO unicode");
|
|
||||||
break;
|
|
||||||
case 'U':
|
|
||||||
zig_panic("TODO Unicode");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return mark_error(ctok);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateStrHex: {
|
|
||||||
uint8_t value = 0;
|
|
||||||
switch (*c) {
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
case '8':
|
|
||||||
case '9':
|
|
||||||
value = *c - '0';
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
case 'b':
|
|
||||||
case 'c':
|
|
||||||
case 'd':
|
|
||||||
case 'e':
|
|
||||||
case 'f':
|
|
||||||
value = (*c - 'a') + 10;
|
|
||||||
break;
|
|
||||||
case 'A':
|
|
||||||
case 'B':
|
|
||||||
case 'C':
|
|
||||||
case 'D':
|
|
||||||
case 'E':
|
|
||||||
case 'F':
|
|
||||||
value = (*c - 'A') + 10;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
add_char(ctok, ctok->cur_char);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// TODO @mul_with_overflow
|
|
||||||
if (((long)ctok->cur_char) * 16 >= 256) {
|
|
||||||
zig_panic("TODO str hex mul overflow");
|
|
||||||
}
|
|
||||||
ctok->cur_char = (uint8_t)(ctok->cur_char * (uint8_t)16);
|
|
||||||
// TODO @add_with_overflow
|
|
||||||
if (((long)ctok->cur_char) + (long)(value) >= 256) {
|
|
||||||
zig_panic("TODO str hex add overflow");
|
|
||||||
}
|
|
||||||
ctok->cur_char = (uint8_t)(ctok->cur_char + value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CTokStateStrOctal:
|
|
||||||
switch (*c) {
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
// TODO @mul_with_overflow
|
|
||||||
if (((long)ctok->cur_char) * 8 >= 256) {
|
|
||||||
zig_panic("TODO");
|
|
||||||
}
|
|
||||||
ctok->cur_char = (uint8_t)(ctok->cur_char * (uint8_t)8);
|
|
||||||
// TODO @add_with_overflow
|
|
||||||
if (((long)ctok->cur_char) + (long)(*c - '0') >= 256) {
|
|
||||||
zig_panic("TODO");
|
|
||||||
}
|
|
||||||
ctok->cur_char = (uint8_t)(ctok->cur_char + (uint8_t)(*c - '0'));
|
|
||||||
ctok->octal_index += 1;
|
|
||||||
if (ctok->octal_index == 3) {
|
|
||||||
add_char(ctok, ctok->cur_char);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 1;
|
|
||||||
add_char(ctok, ctok->cur_char);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateExpectEndQuot:
|
|
||||||
switch (*c) {
|
|
||||||
case '\'':
|
|
||||||
end_token(ctok);
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return mark_error(ctok);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateOpenComment:
|
|
||||||
switch (*c) {
|
|
||||||
case '/':
|
|
||||||
ctok->state = CTokStateLineComment;
|
|
||||||
break;
|
|
||||||
case '*':
|
|
||||||
ctok->state = CTokStateComment;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return mark_error(ctok);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateLineComment:
|
|
||||||
if (*c == '\n') {
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
goto found_end_of_macro;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateComment:
|
|
||||||
switch (*c) {
|
|
||||||
case '*':
|
|
||||||
ctok->state = CTokStateCommentStar;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateCommentStar:
|
|
||||||
switch (*c) {
|
|
||||||
case '/':
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
break;
|
|
||||||
case '*':
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ctok->state = CTokStateComment;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTokStateBackslash:
|
|
||||||
switch (*c) {
|
|
||||||
case '\n':
|
|
||||||
ctok->state = CTokStateStart;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return mark_error(ctok);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
found_end_of_macro:
|
|
||||||
|
|
||||||
switch (ctok->state) {
|
|
||||||
case CTokStateStart:
|
|
||||||
break;
|
|
||||||
case CTokStateIdentifier:
|
|
||||||
case CTokStateDecimal:
|
|
||||||
case CTokStateHex:
|
|
||||||
case CTokStateOctal:
|
|
||||||
case CTokStateGotZero:
|
|
||||||
case CTokStateNumLitIntSuffixU:
|
|
||||||
case CTokStateNumLitIntSuffixL:
|
|
||||||
case CTokStateNumLitIntSuffixUL:
|
|
||||||
case CTokStateNumLitIntSuffixLL:
|
|
||||||
case CTokStateGotLt:
|
|
||||||
end_token(ctok);
|
|
||||||
break;
|
|
||||||
case CTokStateFloat:
|
|
||||||
case CTokStateFloatExp:
|
|
||||||
end_float(ctok);
|
|
||||||
break;
|
|
||||||
case CTokStateExpectChar:
|
|
||||||
case CTokStateExpectEndQuot:
|
|
||||||
case CTokStateOpenComment:
|
|
||||||
case CTokStateLineComment:
|
|
||||||
case CTokStateComment:
|
|
||||||
case CTokStateCommentStar:
|
|
||||||
case CTokStateCharEscape:
|
|
||||||
case CTokStateBackslash:
|
|
||||||
case CTokStateString:
|
|
||||||
case CTokStateExpSign:
|
|
||||||
case CTokStateFloatExpFirst:
|
|
||||||
case CTokStateStrHex:
|
|
||||||
case CTokStateStrOctal:
|
|
||||||
return mark_error(ctok);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(ctok->cur_tok == nullptr);
|
|
||||||
|
|
||||||
begin_token(ctok, CTokIdEOF);
|
|
||||||
end_token(ctok);
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2016 Andrew Kelley
|
|
||||||
*
|
|
||||||
* This file is part of zig, which is MIT licensed.
|
|
||||||
* See http://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ZIG_C_TOKENIZER_HPP
|
|
||||||
#define ZIG_C_TOKENIZER_HPP
|
|
||||||
|
|
||||||
#include "buffer.hpp"
|
|
||||||
|
|
||||||
enum CTokId {
|
|
||||||
CTokIdCharLit,
|
|
||||||
CTokIdStrLit,
|
|
||||||
CTokIdNumLitInt,
|
|
||||||
CTokIdNumLitFloat,
|
|
||||||
CTokIdSymbol,
|
|
||||||
CTokIdMinus,
|
|
||||||
CTokIdLParen,
|
|
||||||
CTokIdRParen,
|
|
||||||
CTokIdEOF,
|
|
||||||
CTokIdDot,
|
|
||||||
CTokIdAsterisk,
|
|
||||||
CTokIdBang,
|
|
||||||
CTokIdTilde,
|
|
||||||
CTokIdShl,
|
|
||||||
CTokIdLt,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CNumLitSuffix {
|
|
||||||
CNumLitSuffixNone,
|
|
||||||
CNumLitSuffixL,
|
|
||||||
CNumLitSuffixU,
|
|
||||||
CNumLitSuffixLU,
|
|
||||||
CNumLitSuffixLL,
|
|
||||||
CNumLitSuffixLLU,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CNumLitInt {
|
|
||||||
uint64_t x;
|
|
||||||
CNumLitSuffix suffix;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CTok {
|
|
||||||
enum CTokId id;
|
|
||||||
union {
|
|
||||||
uint8_t char_lit;
|
|
||||||
Buf str_lit;
|
|
||||||
CNumLitInt num_lit_int;
|
|
||||||
double num_lit_float;
|
|
||||||
Buf symbol;
|
|
||||||
} data;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CTokState {
|
|
||||||
CTokStateStart,
|
|
||||||
CTokStateExpectChar,
|
|
||||||
CTokStateCharEscape,
|
|
||||||
CTokStateExpectEndQuot,
|
|
||||||
CTokStateOpenComment,
|
|
||||||
CTokStateLineComment,
|
|
||||||
CTokStateComment,
|
|
||||||
CTokStateCommentStar,
|
|
||||||
CTokStateBackslash,
|
|
||||||
CTokStateString,
|
|
||||||
CTokStateIdentifier,
|
|
||||||
CTokStateDecimal,
|
|
||||||
CTokStateOctal,
|
|
||||||
CTokStateGotZero,
|
|
||||||
CTokStateHex,
|
|
||||||
CTokStateFloat,
|
|
||||||
CTokStateExpSign,
|
|
||||||
CTokStateFloatExp,
|
|
||||||
CTokStateFloatExpFirst,
|
|
||||||
CTokStateStrHex,
|
|
||||||
CTokStateStrOctal,
|
|
||||||
CTokStateNumLitIntSuffixU,
|
|
||||||
CTokStateNumLitIntSuffixL,
|
|
||||||
CTokStateNumLitIntSuffixLL,
|
|
||||||
CTokStateNumLitIntSuffixUL,
|
|
||||||
CTokStateGotLt,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CTokenize {
|
|
||||||
ZigList<CTok> tokens;
|
|
||||||
CTokState state;
|
|
||||||
bool error;
|
|
||||||
CTok *cur_tok;
|
|
||||||
Buf buf;
|
|
||||||
uint8_t cur_char;
|
|
||||||
int octal_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
void tokenize_c_macro(CTokenize *ctok, const uint8_t *c);
|
|
||||||
|
|
||||||
#endif
|
|
@ -15,7 +15,6 @@
|
|||||||
#include "hash_map.hpp"
|
#include "hash_map.hpp"
|
||||||
#include "ir.hpp"
|
#include "ir.hpp"
|
||||||
#include "os.hpp"
|
#include "os.hpp"
|
||||||
#include "translate_c.hpp"
|
|
||||||
#include "target.hpp"
|
#include "target.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
#include "zig_llvm.h"
|
#include "zig_llvm.h"
|
||||||
@ -9104,7 +9103,7 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_userland_implementation) {
|
void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file) {
|
||||||
Error err;
|
Error err;
|
||||||
Buf *src_basename = buf_alloc();
|
Buf *src_basename = buf_alloc();
|
||||||
Buf *src_dirname = buf_alloc();
|
Buf *src_dirname = buf_alloc();
|
||||||
@ -9117,10 +9116,6 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
|
|||||||
|
|
||||||
init(g);
|
init(g);
|
||||||
|
|
||||||
TranslateMode trans_mode = buf_ends_with_str(full_path, ".h") ?
|
|
||||||
TranslateModeImport : TranslateModeTranslate;
|
|
||||||
|
|
||||||
|
|
||||||
ZigList<const char *> clang_argv = {0};
|
ZigList<const char *> clang_argv = {0};
|
||||||
add_cc_args(g, clang_argv, nullptr, true);
|
add_cc_args(g, clang_argv, nullptr, true);
|
||||||
|
|
||||||
@ -9140,15 +9135,9 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
|
|||||||
Stage2ErrorMsg *errors_ptr;
|
Stage2ErrorMsg *errors_ptr;
|
||||||
size_t errors_len;
|
size_t errors_len;
|
||||||
Stage2Ast *ast;
|
Stage2Ast *ast;
|
||||||
AstNode *root_node;
|
|
||||||
|
|
||||||
if (use_userland_implementation) {
|
err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
|
||||||
err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
|
&clang_argv.at(0), &clang_argv.last(), resources_path);
|
||||||
&clang_argv.at(0), &clang_argv.last(), resources_path);
|
|
||||||
} else {
|
|
||||||
err = parse_h_file(g, &root_node, &errors_ptr, &errors_len, &clang_argv.at(0), &clang_argv.last(),
|
|
||||||
trans_mode, resources_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err == ErrorCCompileErrors && errors_len > 0) {
|
if (err == ErrorCCompileErrors && errors_len > 0) {
|
||||||
for (size_t i = 0; i < errors_len; i += 1) {
|
for (size_t i = 0; i < errors_len; i += 1) {
|
||||||
@ -9172,12 +9161,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stage2_render_ast(ast, out_file);
|
||||||
if (use_userland_implementation) {
|
|
||||||
stage2_render_ast(ast, out_file);
|
|
||||||
} else {
|
|
||||||
ast_render(out_file, root_node, 4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_test_functions_builtin_decl(CodeGen *g) {
|
static void update_test_functions_builtin_decl(CodeGen *g) {
|
||||||
|
@ -54,7 +54,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
|
|||||||
void codegen_add_assembly(CodeGen *g, Buf *path);
|
void codegen_add_assembly(CodeGen *g, Buf *path);
|
||||||
void codegen_add_object(CodeGen *g, Buf *object_path);
|
void codegen_add_object(CodeGen *g, Buf *object_path);
|
||||||
|
|
||||||
void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_userland_implementation);
|
void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file);
|
||||||
|
|
||||||
Buf *codegen_generate_builtin_source(CodeGen *g);
|
Buf *codegen_generate_builtin_source(CodeGen *g);
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include "os.hpp"
|
#include "os.hpp"
|
||||||
#include "range_set.hpp"
|
#include "range_set.hpp"
|
||||||
#include "softfloat.hpp"
|
#include "softfloat.hpp"
|
||||||
#include "translate_c.hpp"
|
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -23762,14 +23761,14 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
|
|||||||
|
|
||||||
clang_argv.append(nullptr); // to make the [start...end] argument work
|
clang_argv.append(nullptr); // to make the [start...end] argument work
|
||||||
|
|
||||||
AstNode *root_node;
|
|
||||||
Stage2ErrorMsg *errors_ptr;
|
Stage2ErrorMsg *errors_ptr;
|
||||||
size_t errors_len;
|
size_t errors_len;
|
||||||
|
Stage2Ast *ast;
|
||||||
|
|
||||||
const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir);
|
const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir);
|
||||||
|
|
||||||
if ((err = parse_h_file(ira->codegen, &root_node, &errors_ptr, &errors_len,
|
if ((err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
|
||||||
&clang_argv.at(0), &clang_argv.last(), TranslateModeImport, resources_path)))
|
&clang_argv.at(0), &clang_argv.last(), resources_path)))
|
||||||
{
|
{
|
||||||
if (err != ErrorCCompileErrors) {
|
if (err != ErrorCCompileErrors) {
|
||||||
ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err)));
|
ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err)));
|
||||||
@ -23820,7 +23819,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
|
|||||||
buf_sprintf("C import failed: unable to open output file: %s", strerror(errno)));
|
buf_sprintf("C import failed: unable to open output file: %s", strerror(errno)));
|
||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
}
|
}
|
||||||
ast_render(out_file, root_node, 4);
|
stage2_render_ast(ast, out_file);
|
||||||
if (fclose(out_file) != 0) {
|
if (fclose(out_file) != 0) {
|
||||||
ir_add_error_node(ira, node,
|
ir_add_error_node(ira, node,
|
||||||
buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno)));
|
buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno)));
|
||||||
|
16
src/main.cpp
16
src/main.cpp
@ -243,7 +243,6 @@ enum Cmd {
|
|||||||
CmdTargets,
|
CmdTargets,
|
||||||
CmdTest,
|
CmdTest,
|
||||||
CmdTranslateC,
|
CmdTranslateC,
|
||||||
CmdTranslateCUserland,
|
|
||||||
CmdVersion,
|
CmdVersion,
|
||||||
CmdZen,
|
CmdZen,
|
||||||
CmdLibC,
|
CmdLibC,
|
||||||
@ -960,8 +959,6 @@ int main(int argc, char **argv) {
|
|||||||
cmd = CmdLibC;
|
cmd = CmdLibC;
|
||||||
} else if (strcmp(arg, "translate-c") == 0) {
|
} else if (strcmp(arg, "translate-c") == 0) {
|
||||||
cmd = CmdTranslateC;
|
cmd = CmdTranslateC;
|
||||||
} else if (strcmp(arg, "translate-c-2") == 0) {
|
|
||||||
cmd = CmdTranslateCUserland;
|
|
||||||
} else if (strcmp(arg, "test") == 0) {
|
} else if (strcmp(arg, "test") == 0) {
|
||||||
cmd = CmdTest;
|
cmd = CmdTest;
|
||||||
out_type = OutTypeExe;
|
out_type = OutTypeExe;
|
||||||
@ -978,7 +975,6 @@ int main(int argc, char **argv) {
|
|||||||
case CmdBuild:
|
case CmdBuild:
|
||||||
case CmdRun:
|
case CmdRun:
|
||||||
case CmdTranslateC:
|
case CmdTranslateC:
|
||||||
case CmdTranslateCUserland:
|
|
||||||
case CmdTest:
|
case CmdTest:
|
||||||
case CmdLibC:
|
case CmdLibC:
|
||||||
if (!in_file) {
|
if (!in_file) {
|
||||||
@ -1112,7 +1108,6 @@ int main(int argc, char **argv) {
|
|||||||
case CmdRun:
|
case CmdRun:
|
||||||
case CmdBuild:
|
case CmdBuild:
|
||||||
case CmdTranslateC:
|
case CmdTranslateC:
|
||||||
case CmdTranslateCUserland:
|
|
||||||
case CmdTest:
|
case CmdTest:
|
||||||
{
|
{
|
||||||
if (cmd == CmdBuild && !in_file && objects.length == 0 &&
|
if (cmd == CmdBuild && !in_file && objects.length == 0 &&
|
||||||
@ -1124,7 +1119,7 @@ int main(int argc, char **argv) {
|
|||||||
" * --object argument\n"
|
" * --object argument\n"
|
||||||
" * --c-source argument\n");
|
" * --c-source argument\n");
|
||||||
return print_error_usage(arg0);
|
return print_error_usage(arg0);
|
||||||
} else if ((cmd == CmdTranslateC || cmd == CmdTranslateCUserland ||
|
} else if ((cmd == CmdTranslateC ||
|
||||||
cmd == CmdTest || cmd == CmdRun) && !in_file)
|
cmd == CmdTest || cmd == CmdRun) && !in_file)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected source file argument.\n");
|
fprintf(stderr, "Expected source file argument.\n");
|
||||||
@ -1136,7 +1131,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
assert(cmd != CmdBuild || out_type != OutTypeUnknown);
|
assert(cmd != CmdBuild || out_type != OutTypeUnknown);
|
||||||
|
|
||||||
bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC || cmd == CmdTranslateCUserland);
|
bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC);
|
||||||
|
|
||||||
if (cmd == CmdRun) {
|
if (cmd == CmdRun) {
|
||||||
out_name = "run";
|
out_name = "run";
|
||||||
@ -1170,8 +1165,7 @@ int main(int argc, char **argv) {
|
|||||||
return print_error_usage(arg0);
|
return print_error_usage(arg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Buf *zig_root_source_file = (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) ?
|
Buf *zig_root_source_file = cmd == CmdTranslateC ? nullptr : in_file_buf;
|
||||||
nullptr : in_file_buf;
|
|
||||||
|
|
||||||
if (cmd == CmdRun && buf_out_name == nullptr) {
|
if (cmd == CmdRun && buf_out_name == nullptr) {
|
||||||
buf_out_name = buf_create_from_str("run");
|
buf_out_name = buf_create_from_str("run");
|
||||||
@ -1336,8 +1330,8 @@ int main(int argc, char **argv) {
|
|||||||
} else {
|
} else {
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
} else if (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) {
|
} else if (cmd == CmdTranslateC) {
|
||||||
codegen_translate_c(g, in_file_buf, stdout, cmd == CmdTranslateCUserland);
|
codegen_translate_c(g, in_file_buf, stdout);
|
||||||
if (timing_info)
|
if (timing_info)
|
||||||
codegen_print_timing_report(g, stderr);
|
codegen_print_timing_report(g, stderr);
|
||||||
return main_exit(root_progress_node, EXIT_SUCCESS);
|
return main_exit(root_progress_node, EXIT_SUCCESS);
|
||||||
|
5156
src/translate_c.cpp
5156
src/translate_c.cpp
File diff suppressed because it is too large
Load Diff
@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015 Andrew Kelley
|
|
||||||
*
|
|
||||||
* This file is part of zig, which is MIT licensed.
|
|
||||||
* See http://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ZIG_PARSEC_HPP
|
|
||||||
#define ZIG_PARSEC_HPP
|
|
||||||
|
|
||||||
#include "all_types.hpp"
|
|
||||||
|
|
||||||
enum TranslateMode {
|
|
||||||
TranslateModeImport,
|
|
||||||
TranslateModeTranslate,
|
|
||||||
};
|
|
||||||
|
|
||||||
Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
|
|
||||||
Stage2ErrorMsg **errors_ptr, size_t *errors_len,
|
|
||||||
const char **args_begin, const char **args_end,
|
|
||||||
TranslateMode mode, const char *resources_path);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1686,6 +1686,16 @@ const struct ZigClangStmt *ZigClangFunctionDecl_getBody(const struct ZigClangFun
|
|||||||
return reinterpret_cast<const ZigClangStmt *>(stmt);
|
return reinterpret_cast<const ZigClangStmt *>(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(const struct ZigClangFunctionDecl *self) {
|
||||||
|
auto casted = reinterpret_cast<const clang::FunctionDecl *>(self);
|
||||||
|
return casted->doesDeclarationForceExternallyVisibleDefinition();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZigClangFunctionDecl_isInlineSpecified(const struct ZigClangFunctionDecl *self) {
|
||||||
|
auto casted = reinterpret_cast<const clang::FunctionDecl *>(self);
|
||||||
|
return casted->isInlineSpecified();
|
||||||
|
}
|
||||||
|
|
||||||
const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) {
|
const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) {
|
||||||
auto casted = reinterpret_cast<const clang::TypedefType *>(self);
|
auto casted = reinterpret_cast<const clang::TypedefType *>(self);
|
||||||
const clang::TypedefNameDecl *name_decl = casted->getDecl();
|
const clang::TypedefNameDecl *name_decl = casted->getDecl();
|
||||||
|
@ -873,6 +873,8 @@ ZIG_EXTERN_C bool ZigClangFunctionDecl_hasBody(const struct ZigClangFunctionDecl
|
|||||||
ZIG_EXTERN_C enum ZigClangStorageClass ZigClangFunctionDecl_getStorageClass(const struct ZigClangFunctionDecl *);
|
ZIG_EXTERN_C enum ZigClangStorageClass ZigClangFunctionDecl_getStorageClass(const struct ZigClangFunctionDecl *);
|
||||||
ZIG_EXTERN_C const struct ZigClangParmVarDecl *ZigClangFunctionDecl_getParamDecl(const struct ZigClangFunctionDecl *, unsigned i);
|
ZIG_EXTERN_C const struct ZigClangParmVarDecl *ZigClangFunctionDecl_getParamDecl(const struct ZigClangFunctionDecl *, unsigned i);
|
||||||
ZIG_EXTERN_C const struct ZigClangStmt *ZigClangFunctionDecl_getBody(const struct ZigClangFunctionDecl *);
|
ZIG_EXTERN_C const struct ZigClangStmt *ZigClangFunctionDecl_getBody(const struct ZigClangFunctionDecl *);
|
||||||
|
ZIG_EXTERN_C bool ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(const struct ZigClangFunctionDecl *);
|
||||||
|
ZIG_EXTERN_C bool ZigClangFunctionDecl_isInlineSpecified(const struct ZigClangFunctionDecl *);
|
||||||
|
|
||||||
ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const struct ZigClangRecordDecl *record_decl);
|
ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const struct ZigClangRecordDecl *record_decl);
|
||||||
ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const struct ZigClangRecordDecl *record_decl);
|
ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const struct ZigClangRecordDecl *record_decl);
|
||||||
|
@ -5,7 +5,11 @@ const tests = @import("tests.zig");
|
|||||||
|
|
||||||
pub fn addCases(cases: *tests.CompareOutputContext) void {
|
pub fn addCases(cases: *tests.CompareOutputContext) void {
|
||||||
cases.addC("hello world with libc",
|
cases.addC("hello world with libc",
|
||||||
\\const c = @cImport(@cInclude("stdio.h"));
|
\\const c = @cImport({
|
||||||
|
\\ // See https://github.com/ziglang/zig/issues/515
|
||||||
|
\\ @cDefine("_NO_CRT_STDIO_INLINE", "1");
|
||||||
|
\\ @cInclude("stdio.h");
|
||||||
|
\\});
|
||||||
\\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
|
\\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
|
||||||
\\ _ = c.puts("Hello, world!");
|
\\ _ = c.puts("Hello, world!");
|
||||||
\\ return 0;
|
\\ return 0;
|
||||||
|
@ -1422,7 +1422,6 @@ pub const TranslateCContext = struct {
|
|||||||
sources: ArrayList(SourceFile),
|
sources: ArrayList(SourceFile),
|
||||||
expected_lines: ArrayList([]const u8),
|
expected_lines: ArrayList([]const u8),
|
||||||
allow_warnings: bool,
|
allow_warnings: bool,
|
||||||
stage2: bool,
|
|
||||||
|
|
||||||
const SourceFile = struct {
|
const SourceFile = struct {
|
||||||
filename: []const u8,
|
filename: []const u8,
|
||||||
@ -1475,7 +1474,7 @@ pub const TranslateCContext = struct {
|
|||||||
var zig_args = ArrayList([]const u8).init(b.allocator);
|
var zig_args = ArrayList([]const u8).init(b.allocator);
|
||||||
zig_args.append(b.zig_exe) catch unreachable;
|
zig_args.append(b.zig_exe) catch unreachable;
|
||||||
|
|
||||||
const translate_c_cmd = if (self.case.stage2) "translate-c-2" else "translate-c";
|
const translate_c_cmd = "translate-c";
|
||||||
zig_args.append(translate_c_cmd) catch unreachable;
|
zig_args.append(translate_c_cmd) catch unreachable;
|
||||||
zig_args.append(b.pathFromRoot(root_src)) catch unreachable;
|
zig_args.append(b.pathFromRoot(root_src)) catch unreachable;
|
||||||
|
|
||||||
@ -1583,7 +1582,6 @@ pub const TranslateCContext = struct {
|
|||||||
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
|
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
|
||||||
.expected_lines = ArrayList([]const u8).init(self.b.allocator),
|
.expected_lines = ArrayList([]const u8).init(self.b.allocator),
|
||||||
.allow_warnings = allow_warnings,
|
.allow_warnings = allow_warnings,
|
||||||
.stage2 = false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tc.addSourceFile(filename, source);
|
tc.addSourceFile(filename, source);
|
||||||
@ -1604,53 +1602,6 @@ pub const TranslateCContext = struct {
|
|||||||
self.addCase(tc);
|
self.addCase(tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn addC(
|
|
||||||
self: *TranslateCContext,
|
|
||||||
name: []const u8,
|
|
||||||
source: []const u8,
|
|
||||||
expected_lines: []const []const u8,
|
|
||||||
) void {
|
|
||||||
const tc = self.create(false, "source.c", name, source, expected_lines);
|
|
||||||
self.addCase(tc);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_both(
|
|
||||||
self: *TranslateCContext,
|
|
||||||
name: []const u8,
|
|
||||||
source: []const u8,
|
|
||||||
expected_lines: []const []const u8,
|
|
||||||
) void {
|
|
||||||
for ([_]bool{ false, true }) |stage2| {
|
|
||||||
const tc = self.create(false, "source.h", name, source, expected_lines);
|
|
||||||
tc.stage2 = stage2;
|
|
||||||
self.addCase(tc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn addC_both(
|
|
||||||
self: *TranslateCContext,
|
|
||||||
name: []const u8,
|
|
||||||
source: []const u8,
|
|
||||||
expected_lines: []const []const u8,
|
|
||||||
) void {
|
|
||||||
for ([_]bool{ false, true }) |stage2| {
|
|
||||||
const tc = self.create(false, "source.c", name, source, expected_lines);
|
|
||||||
tc.stage2 = stage2;
|
|
||||||
self.addCase(tc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_2(
|
|
||||||
self: *TranslateCContext,
|
|
||||||
name: []const u8,
|
|
||||||
source: []const u8,
|
|
||||||
expected_lines: []const []const u8,
|
|
||||||
) void {
|
|
||||||
const tc = self.create(false, "source.h", name, source, expected_lines);
|
|
||||||
tc.stage2 = true;
|
|
||||||
self.addCase(tc);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn addAllowWarnings(
|
pub fn addAllowWarnings(
|
||||||
self: *TranslateCContext,
|
self: *TranslateCContext,
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
@ -1664,7 +1615,7 @@ pub const TranslateCContext = struct {
|
|||||||
pub fn addCase(self: *TranslateCContext, case: *const TestCase) void {
|
pub fn addCase(self: *TranslateCContext, case: *const TestCase) void {
|
||||||
const b = self.b;
|
const b = self.b;
|
||||||
|
|
||||||
const translate_c_cmd = if (case.stage2) "translate-c-2" else "translate-c";
|
const translate_c_cmd = "translate-c";
|
||||||
const annotated_case_name = fmt.allocPrint(self.b.allocator, "{} {}", .{ translate_c_cmd, case.name }) catch unreachable;
|
const annotated_case_name = fmt.allocPrint(self.b.allocator, "{} {}", .{ translate_c_cmd, case.name }) catch unreachable;
|
||||||
if (self.test_filter) |filter| {
|
if (self.test_filter) |filter| {
|
||||||
if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
|
if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
|
||||||
|
1812
test/translate_c.zig
1812
test/translate_c.zig
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user