tiny.chant.parse
Defined in tiny.chant.
API (24)
Actions
Public operations.
initparse: Parsestokensinto a translation unit whose expression, statement and type nodes sit innodesand refer to one another by pointer, so lowering (translating each parsed C function into Choir operations) can consume the result.parseExpressionparseExternalparseStatementparseTranslationUnitsurvey
Types and contracts
Public types and contracts.
CapacityCapacityErrorDiagnosticErrorExhaustionLimitsParserStorage: The storage divides one buffer the caller supplies into slots for up to two expression nodes, one statement node and two type nodes per admitted token, along with the source token and cached inferred type of each node.Survey: The record stores the address and length of one lexed token slice, and a token limit equal to that length.TypeOriginTypePlacement
Namespaces
Public namespaces.
Source
Source: lib/chant/src/parse/error.zig:1
zig
pub const Error = error{ OutOfMemory, NodeCapacityExceeded, UnexpectedToken, ExpectedType, ExpectedIdentifier, InvalidConstant, StaticAssertionFailed, UnsupportedConstruct,};Source: lib/chant/src/parse/external.zig:20
zig
pub fn parseExternal(parser: *Parser) Error![]ast.Decl { if (try assertion.consume(parser)) { return &.{}; } const specifiers = try ctype.parseSpecifiers(parser); var declarations = std.ArrayListUnmanaged(ast.Decl).empty; if (cursor.consume(parser, .semicolon)) { return declarations.toOwnedSlice(parser.arena); } if (specifiers.requires_standalone_declaration) { return diagnostic.fail(parser, error.UnsupportedConstruct, "fixed enum forward declaration must be standalone"); } var first = true; while (true) { try ctype.skipAttributes(parser); const declarator = try ctype.parseDeclarator(parser, specifiers.type, expression.parseAssignment); try ctype.skipAttributes(parser); const name = declarator.name orelse return diagnostic.fail(parser, error.ExpectedIdentifier, "declaration requires a name"); if (specifiers.storage == .typedef_storage) { try thread.validateTypedef(parser, specifiers.is_thread_local); if (specifiers.is_constexpr) { return diagnostic.fail(parser, error.UnsupportedConstruct, "typedef cannot be constexpr"); } if (auto_mod.contains(declarator.type)) { return diagnostic.fail(parser, error.ExpectedType, "typedef cannot infer auto"); } try typedef.register(parser, name, declarator.type); } else if (declarator.type.kind == .function) { if (auto_mod.contains(declarator.type)) { return diagnostic.fail(parser, error.ExpectedType, "function declarations cannot infer auto"); } if (specifiers.alignment != null) { return diagnostic.fail(parser, error.UnsupportedConstruct, "alignas on function declarations is not supported"); } if (specifiers.is_constexpr) { return diagnostic.fail(parser, error.UnsupportedConstruct, "function declarations cannot be constexpr"); } try thread.validateFunction(parser, specifiers.is_thread_local); try object.register(parser, name, declarator.type); if (first and cursor.peek(parser).kind == .lbrace) { try object.push(parser); defer object.pop(parser); for (declarator.type.params) |param| { if (param.name.len != 0) try object.register(parser, param.name, param.type); } const body = try statement.parseCompound(parser); try declarations.append(parser.arena, .{ .function = .{ .name = name, .type = declarator.type, .storage = specifiers.storage, .body = body, } }); return declarations.toOwnedSlice(parser.arena); } try declarations.append(parser.arena, .{ .function = .{ .name = name, .type = declarator.type, .storage = specifiers.storage, .body = null, } }); } else { var initializer: ?*ast.Expr = null; if (cursor.consume(parser, .assign)) { initializer = try initializer_mod.parse(parser, declarator.type); } const completed_type = try initializer_mod.completeType(parser, declarator.type, initializer); const variable_type = try auto_mod.resolve(parser, completed_type, initializer); const constant_value = if (specifiers.is_constexpr) try constexpr.validateObject(parser, variable_type, initializer) else null; try thread.validateObject(parser, .file, specifiers.storage, variable_type, initializer, specifiers.is_thread_local); try declarations.append(parser.arena, .{ .variable = .{ .name = name, .type = variable_type, .storage = specifiers.storage, .alignment = specifiers.alignment, .is_constexpr = specifiers.is_constexpr, .is_thread_local = specifiers.is_thread_local, .initializer = initializer, } }); if (specifiers.is_constexpr) { try constexpr.registerObject(parser, name, variable_type, constant_value); } else { try object.register(parser, name, variable_type); } } first = false; if (cursor.consume(parser, .comma)) continue; _ = try cursor.expect(parser, .semicolon); break; } return declarations.toOwnedSlice(parser.arena);}Source: lib/chant/src/parse/statement.zig:17
zig
pub fn parseStatement(parser: *Parser) Error!*ast.Stmt { if (isLabel(parser)) return parseLabel(parser); switch (cursor.peek(parser).kind) { .lbrace => return parseCompound(parser), .semicolon => { _ = cursor.advance(parser); return memory.create(parser, ast.Stmt, .empty); }, .kw_if => return parseIf(parser), .kw_for => return parseFor(parser), .kw_while => return parseWhile(parser), .kw_do => return parseDo(parser), .kw_return => { _ = cursor.advance(parser); var value: ?*ast.Expr = null; if (cursor.peek(parser).kind != .semicolon) { value = try expression.parseExpression(parser); } _ = try cursor.expect(parser, .semicolon); return memory.create(parser, ast.Stmt, .{ .return_stmt = value }); }, .kw_break => { _ = cursor.advance(parser); _ = try cursor.expect(parser, .semicolon); return memory.create(parser, ast.Stmt, .break_stmt); }, .kw_continue => { _ = cursor.advance(parser); _ = try cursor.expect(parser, .semicolon); return memory.create(parser, ast.Stmt, .continue_stmt); }, else => { const value = try expression.parseExpression(parser); _ = try cursor.expect(parser, .semicolon); return memory.create(parser, ast.Stmt, .{ .expression = value }); }, }}Source: lib/chant/src/parse/unit.zig:12
zig
pub fn parseTranslationUnit(self: *Parser) Error!ast.TranslationUnit { var declarations = std.ArrayListUnmanaged(ast.Decl).empty; while (cursor.peek(self).kind != .eof) { if (cursor.consume(self, .semicolon)) continue; if (try ctype.consumeAttributeDeclaration(self)) continue; try ctype.skipAttributes(self); if (cursor.consume(self, .semicolon)) continue; if (try assertion.consume(self)) continue; const parsed = try external.parseExternal(self); try declarations.appendSlice(self.arena, parsed); } return .{ .declarations = try declarations.toOwnedSlice(self.arena) };}Source: lib/chant/src/parse/root.zig
zig
const std = @import("std");const chant = @import("../root.zig");const ast = @import("../ast/root.zig");const statement = @import("statement.zig");const external = @import("external.zig");const translation = @import("unit.zig");pub const Error = @import("error.zig").Error;pub const assertion = @import("assert.zig");pub const auto = @import("auto.zig");pub const expression = @import("expression.zig");pub const initializer = @import("initializer.zig");pub const thread = @import("thread.zig");const Token = chant.token.Token;pub const state = @import("state/root.zig");pub const Diagnostic = state.Diagnostic;pub const Parser = state.Parser;pub const Storage = state.Storage;pub const Limits = state.Limits;pub const Capacity = state.Capacity;pub const CapacityError = state.CapacityError;pub const Survey = state.Survey;pub const Exhaustion = state.Exhaustion;pub const TypeOrigin = state.TypeOrigin;pub const TypePlacement = state.TypePlacement;pub const survey = state.survey;pub const init = state.init;/// Parses `tokens` into a translation unit whose expression, statement and type/// nodes sit in `nodes` and refer to one another by pointer, so lowering/// (translating each parsed C function into Choir operations) can consume the/// result. The call first admits `node_survey` (the record a counting pass/// produced over the tokens) into `nodes`, which clears the node counts. The/// call returns `error.SurveyTokensMismatch` when the survey was taken over a/// different token slice or `error.NodeCapacityExceeded` when it asks for more/// than the storage holds. The tree borrows `nodes`, parser node storage (a/// byte buffer the caller allocates). The caller keeps that storage alive, and/// parses nothing else into it, until it is done with the tree, and the/// compiler driver finishes lowering before it releases the storage. The name/// tables, scopes and lists the parser builds along the way come from `arena`.pub fn parse( arena: std.mem.Allocator, nodes: *Storage, node_survey: Survey, tokens: []const Token,) (Error || Exhaustion)!ast.TranslationUnit { var parser = try init(arena, nodes, node_survey, tokens); return translation.parseTranslationUnit(&parser);}pub const parseExternal = external.parseExternal;pub const parseTranslationUnit = translation.parseTranslationUnit;pub const parseStatement = statement.parseStatement;pub const parseExpression = expression.parseExpression;Source: lib/chant/src/root.zig:62
zig
pub const parse = @import("parse/root.zig");Complete call list for parse.parseExternal
14 direct calls.
lib.chant.src.parse.constexpr.registerObject[function] — private source atlib/chant/src/parse/constexpr.zig:23in nearest public ownerlib.chant.src.parse.constexprlib.chant.src.parse.constexpr.validateObject[function] — private source atlib/chant/src/parse/constexpr.zig:11in nearest public ownerlib.chant.src.parse.constexprtiny.chant.parse.state.cursor.consume[function] atlib/chant/src/parse/state/cursor.zig:26tiny.chant.parse.state.cursor.expect[function] atlib/chant/src/parse/state/cursor.zig:34tiny.chant.parse.state.cursor.peek[function] atlib/chant/src/parse/state/cursor.zig:11tiny.chant.parse.state.diagnostic.fail[function] atlib/chant/src/parse/state/diagnostic.zig:9tiny.chant.parse.state.object.pop[function] atlib/chant/src/parse/state/object.zig:14tiny.chant.parse.state.object.push[function] atlib/chant/src/parse/state/object.zig:10tiny.chant.parse.state.object.register[function] atlib/chant/src/parse/state/object.zig:19tiny.chant.parse.state.typedef.register[function] atlib/chant/src/parse/state/typedef.zig:18lib.chant.src.parse.statement.parseCompound[function] — private source atlib/chant/src/parse/statement.zig:56in nearest public ownerlib.chant.src.parse.statementtiny.chant.parse.thread.validateFunction[function] atlib/chant/src/parse/thread.zig:20tiny.chant.parse.thread.validateObject[function] atlib/chant/src/parse/thread.zig:32tiny.chant.parse.thread.validateTypedef[function] atlib/chant/src/parse/thread.zig:14
Complete call list for parse.parseStatement
12 direct calls.
tiny.chant.parse.expression.parseExpression[function] atlib/chant/src/parse/expression.zig:17tiny.chant.parse.state.cursor.advance[function] atlib/chant/src/parse/state/cursor.zig:20tiny.chant.parse.state.cursor.expect[function] atlib/chant/src/parse/state/cursor.zig:34tiny.chant.parse.state.cursor.peek[function] atlib/chant/src/parse/state/cursor.zig:11tiny.chant.parse.state.memory.create[function] atlib/chant/src/parse/state/memory.zig:8lib.chant.src.parse.statement.isLabel[function] — private source atlib/chant/src/parse/statement.zig:87in nearest public ownerlib.chant.src.parse.statementlib.chant.src.parse.statement.parseCompound[function] — private source atlib/chant/src/parse/statement.zig:56in nearest public ownerlib.chant.src.parse.statementlib.chant.src.parse.statement.parseDo[function] — private source atlib/chant/src/parse/statement.zig:164in nearest public ownerlib.chant.src.parse.statementlib.chant.src.parse.statement.parseFor[function] — private source atlib/chant/src/parse/statement.zig:118in nearest public ownerlib.chant.src.parse.statementlib.chant.src.parse.statement.parseIf[function] — private source atlib/chant/src/parse/statement.zig:101in nearest public ownerlib.chant.src.parse.statementlib.chant.src.parse.statement.parseLabel[function] — private source atlib/chant/src/parse/statement.zig:91in nearest public ownerlib.chant.src.parse.statementlib.chant.src.parse.statement.parseWhile[function] — private source atlib/chant/src/parse/statement.zig:155in nearest public ownerlib.chant.src.parse.statement
Audit
| Definitions | 6 |
|---|---|
| Public names | 6 |
| Members | 8 |
| Version | 26.7.0 |
| Revision | daab053ee433 |