Generate internal enum types.

This commit is contained in:
Chris Fallin
2021-09-04 12:59:19 -07:00
parent 5aa72bc060
commit e9a57d854d
3 changed files with 63 additions and 10 deletions

View File

@@ -2,8 +2,9 @@
use crate::error::Error;
use crate::ir::{lower_rule, ExprSequence, PatternInst, PatternSequence};
use crate::sema::{RuleId, TermEnv, TermId, TypeEnv};
use crate::sema::{RuleId, TermEnv, TermId, Type, TypeEnv};
use std::collections::HashMap;
use std::fmt::Write;
/// One "input symbol" for the decision tree that handles matching on
/// a term. Each symbol represents one step: we either run a match op,
@@ -509,9 +510,49 @@ impl<'a> Codegen<'a> {
}
pub fn generate_rust(&self) -> Result<String, Error> {
use std::fmt::Write;
let mut code = String::new();
writeln!(&mut code, "// GENERATED BY ISLE. DO NOT EDIT!")?;
writeln!(
&mut code,
"use super::*; // Pulls in all external types and ctors/etors"
)?;
self.generate_internal_types(&mut code)?;
Ok(code)
}
fn generate_internal_types(&self, code: &mut dyn Write) -> Result<(), Error> {
for ty in &self.typeenv.types {
match ty {
&Type::Enum {
name,
is_extern,
ref variants,
pos,
..
} if !is_extern => {
let name = &self.typeenv.syms[name.index()];
writeln!(
code,
"\n// Internal type {}: defined at {}.",
name,
pos.pretty_print_line(&self.typeenv.filename)
)?;
writeln!(code, "enum {} {{", name)?;
for variant in variants {
let name = &self.typeenv.syms[variant.name.index()];
writeln!(code, " {} {{", name)?;
for field in &variant.fields {
let name = &self.typeenv.syms[field.name.index()];
let ty_name = self.typeenv.types[field.ty.index()].name(&self.typeenv);
writeln!(code, " {}: {},", name, ty_name)?;
}
writeln!(code, " }}")?;
}
writeln!(code, "}}")?;
}
_ => {}
}
}
Ok(())
}
}