1
0
Fork 0
mirror of https://github.com/imjasonh/nescript synced 2026-07-12 18:49:45 +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:
Claude 2026-04-12 11:36:44 +00:00
parent ae051f5909
commit dbfcb313bc
No known key found for this signature in database
12 changed files with 181 additions and 0 deletions

View file

@ -107,6 +107,11 @@ impl Analyzer {
self.register_const(c);
}
// Register enum variants as constants with values 0, 1, 2, ...
for e in &program.enums {
self.register_enum(e);
}
// Register and allocate globals
for var in &program.globals {
self.register_var(var);
@ -411,6 +416,39 @@ impl Analyzer {
);
}
/// Register each variant of an enum declaration as a `u8` constant
/// with a value equal to its declaration order. Variant names must
/// be globally unique; a duplicate name emits E0501.
fn register_enum(&mut self, e: &EnumDecl) {
if self.symbols.contains_key(&e.name) {
self.diagnostics.push(Diagnostic::error(
ErrorCode::E0501,
format!("duplicate declaration of '{}'", e.name),
e.span,
));
// Don't return — still register the variants.
}
for (variant_name, variant_span) in &e.variants {
if self.symbols.contains_key(variant_name) {
self.diagnostics.push(Diagnostic::error(
ErrorCode::E0501,
format!("duplicate declaration of '{variant_name}'"),
*variant_span,
));
continue;
}
self.symbols.insert(
variant_name.clone(),
Symbol {
name: variant_name.clone(),
sym_type: NesType::U8,
is_const: true,
span: *variant_span,
},
);
}
}
fn register_var(&mut self, var: &VarDecl) {
if self.symbols.contains_key(&var.name) {
self.diagnostics.push(Diagnostic::error(