mirror of
https://github.com/imjasonh/nescript
synced 2026-07-08 08:55:38 +00:00
Language: enum declarations
Adds \`enum Name { V1, V2, ... }\` as a top-level declaration. Each
variant is registered as a \`u8\` constant equal to its index in the
declaration. Variant names are global and must be unique across all
enums and other symbols (E0501 on collision).
- Lexer: \`enum\` keyword
- AST: \`EnumDecl { name, variants, span }\` field on \`Program\`
- Parser: top-level \`enum\` syntax with optional trailing commas
- Analyzer: \`register_enum\` flattens variants into the symbol table
- IR lowering and AST codegen: variants resolve through the existing
\`const_values\` path
- Tests cover parsing, duplicate detection, and usage
https://claude.ai/code/session_01W6eQFStA66EuMKHUFo2rx3
This commit is contained in:
parent
ae051f5909
commit
dbfcb313bc
12 changed files with 181 additions and 0 deletions
|
|
@ -116,6 +116,7 @@ impl Parser {
|
|||
let mut game = None;
|
||||
let mut globals = Vec::new();
|
||||
let mut constants = Vec::new();
|
||||
let mut enums: Vec<EnumDecl> = Vec::new();
|
||||
let mut functions = Vec::new();
|
||||
let mut states = Vec::new();
|
||||
let mut sprites = Vec::new();
|
||||
|
|
@ -143,6 +144,9 @@ impl Parser {
|
|||
TokenKind::KwConst => {
|
||||
constants.push(self.parse_const_decl()?);
|
||||
}
|
||||
TokenKind::KwEnum => {
|
||||
enums.push(self.parse_enum_decl()?);
|
||||
}
|
||||
TokenKind::KwState => {
|
||||
states.push(self.parse_state_decl()?);
|
||||
}
|
||||
|
|
@ -216,6 +220,7 @@ impl Parser {
|
|||
game,
|
||||
globals,
|
||||
constants,
|
||||
enums,
|
||||
functions,
|
||||
states,
|
||||
sprites,
|
||||
|
|
@ -227,6 +232,41 @@ impl Parser {
|
|||
})
|
||||
}
|
||||
|
||||
fn parse_enum_decl(&mut self) -> Result<EnumDecl, Diagnostic> {
|
||||
let start = self.current_span();
|
||||
self.expect(&TokenKind::KwEnum)?;
|
||||
let (name, _) = self.expect_ident()?;
|
||||
self.expect(&TokenKind::LBrace)?;
|
||||
let mut variants = Vec::new();
|
||||
while *self.peek() != TokenKind::RBrace && *self.peek() != TokenKind::Eof {
|
||||
let span = self.current_span();
|
||||
let (vname, _) = self.expect_ident()?;
|
||||
variants.push((vname, span));
|
||||
if *self.peek() == TokenKind::Comma {
|
||||
self.advance();
|
||||
} else if *self.peek() != TokenKind::RBrace {
|
||||
return Err(Diagnostic::error(
|
||||
ErrorCode::E0201,
|
||||
"expected ',' or '}' in enum body",
|
||||
self.current_span(),
|
||||
));
|
||||
}
|
||||
}
|
||||
self.expect(&TokenKind::RBrace)?;
|
||||
if variants.len() > 256 {
|
||||
return Err(Diagnostic::error(
|
||||
ErrorCode::E0201,
|
||||
"enum has more than 256 variants (u8 overflow)",
|
||||
start,
|
||||
));
|
||||
}
|
||||
Ok(EnumDecl {
|
||||
name,
|
||||
variants,
|
||||
span: Span::new(start.file_id, start.start, self.current_span().end),
|
||||
})
|
||||
}
|
||||
|
||||
// ── Game declaration ──
|
||||
|
||||
fn parse_game_decl(&mut self) -> Result<GameDecl, Diagnostic> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue