tiny.smg.tree.scanner.cpp
Defined in tree.scanner.
API (9)
Actions
Public operations.
Types and contracts
Public types and contracts.
Values and defaults
Public values and defaults.
Source
Source: tools/smg/src/tree/scanner/cpp.zig
zig
const std = @import("std");const builtin = @import("builtin");pub const Token = enum(u16) { raw_string_delimiter, raw_string_content,};pub const Valid = packed struct(u8) { raw_string_delimiter: bool = false, raw_string_content: bool = false, _: u6 = 0,};pub const Scanner = struct { delimiter_length: u8 = 0, delimiter: [maximum_delimiter_length]WChar = @as([maximum_delimiter_length]WChar, @splat(0)), pub const maximum_delimiter_length = 16; pub const serialization_buffer_size = 1024; pub const WChar: type = switch (builtin.target.os.tag) { .windows => u16, .macos, .ios, .tvos, .watchos, .visionos => i32, .linux, .freebsd => if (builtin.target.cpu.arch.isArm() or builtin.target.cpu.arch.isAARCH64()) u32 else i32, else => std.c.wchar_t, }; pub fn scan(self: *Scanner, lexer: anytype, valid: Valid) bool { if (valid.raw_string_delimiter and valid.raw_string_content) return false; if (valid.raw_string_delimiter) { lexer.setResult(@backingInt(Token.raw_string_delimiter)); return self.scanDelimiter(lexer); } if (valid.raw_string_content) { lexer.setResult(@backingInt(Token.raw_string_content)); return self.scanContent(lexer); } return false; } pub fn serialize(self: *const Scanner, buffer: []u8) usize { const size = @as(usize, self.delimiter_length) * @sizeOf(WChar); std.debug.assert(buffer.len >= size); @memcpy(buffer[0..size], std.mem.sliceAsBytes(self.delimiter[0..self.delimiter_length])); return size; } pub fn deserialize(self: *Scanner, serialized: []const u8) void { std.debug.assert(serialized.len % @sizeOf(WChar) == 0); const delimiter_length = serialized.len / @sizeOf(WChar); std.debug.assert(delimiter_length <= maximum_delimiter_length); self.delimiter_length = @intCast(delimiter_length); @memcpy(std.mem.sliceAsBytes(self.delimiter[0..delimiter_length]), serialized); } fn reset(self: *Scanner) void { self.delimiter_length = 0; @memset(&self.delimiter, 0); } fn scanDelimiter(self: *Scanner, lexer: anytype) bool { if (self.delimiter_length > 0) { var index: usize = 0; while (index < self.delimiter_length) : (index += 1) { if (lexer.lookahead() != fromWChar(self.delimiter[index])) return false; lexer.advance(false); } self.reset(); return true; } while (true) { if (self.delimiter_length >= maximum_delimiter_length or lexer.eof() or lexer.lookahead() == '\\' or isSpace(lexer.lookahead())) { return false; } if (lexer.lookahead() == '(') return self.delimiter_length > 0; self.delimiter[self.delimiter_length] = toWChar(lexer.lookahead()); self.delimiter_length += 1; lexer.advance(false); } } fn scanContent(self: *Scanner, lexer: anytype) bool { var delimiter_index: i32 = -1; while (true) { if (lexer.eof()) { lexer.markEnd(); return true; } if (delimiter_index >= 0) { if (delimiter_index == self.delimiter_length) { if (lexer.lookahead() == '"') return true; delimiter_index = -1; } else if (lexer.lookahead() == fromWChar(self.delimiter[@intCast(delimiter_index)])) { delimiter_index += 1; } else { delimiter_index = -1; } } if (delimiter_index == -1 and lexer.lookahead() == ')') { lexer.markEnd(); delimiter_index = 0; } lexer.advance(false); } }};comptime { if (Scanner.maximum_delimiter_length * @sizeOf(Scanner.WChar) >= Scanner.serialization_buffer_size) { @compileError("C++ raw string delimiter state exceeds the scanner serialization buffer"); }}fn isSpace(value: i32) bool { return value == ' ' or value >= '\t' and value <= '\r';}fn toWChar(value: i32) Scanner.WChar { const Unsigned = @Int(.unsigned, @bitSizeOf(Scanner.WChar)); const narrowed: Unsigned = @truncate(@as(u32, @bitCast(value))); return @bitCast(narrowed);}fn fromWChar(value: Scanner.WChar) i32 { return @intCast(value);}Source: tools/smg/src/tree/scanner/root.zig:1
zig
pub const cpp = @import("cpp.zig");Audit
| Definitions | 10 |
|---|---|
| Public names | 10 |
| Members | 7 |
| Version | 26.7.0 |
| Revision | daab053ee433 |