verilization_compiler/lang/
mod.rs1pub mod generator;
4
5use crate::model;
6use std::ffi::OsString;
7use std::io;
8use std::path::Path;
9use num_bigint::BigUint;
10use std::marker::PhantomData;
11
12#[derive(Debug)]
14pub enum GeneratorError {
15 IOError(io::Error),
16 UnknownLanguage(String),
17 InvalidOptions(String),
18 UnmappedPackage(model::PackageName),
19 CouldNotFind(model::QualifiedName),
20 CouldNotFindVersion(model::QualifiedName, BigUint),
21 CouldNotResolveTypeParameter(String),
22 TypeCannotBeSequence(model::QualifiedName),
23 TypeDoesNotHaveCase(model::QualifiedName, Option<BigUint>, String),
24 IncorrectCaseArity(model::QualifiedName, String),
25 RecordLiteralNotForStruct,
26 ExternTypeDoesNotHaveRecordLiteral(model::QualifiedName),
27 CouldNotFindRecordField(model::QualifiedName, Option<BigUint>, String),
28 CouldNotGenerateType,
29 InvalidTypeForConstant,
30 InvalidTypeForCodec,
31}
32
33impl From<io::Error> for GeneratorError {
34 fn from(err: io::Error) -> Self {
35 GeneratorError::IOError(err)
36 }
37}
38
39pub trait OutputHandler<'state> {
43 type FileHandle : io::Write;
44 fn create_file<P: AsRef<Path>>(&'state mut self, path: P) -> Result<Self::FileHandle, GeneratorError>;
45}
46
47pub trait Language {
49
50 type OptionsBuilder;
52
53 type Options;
55
56 fn name() -> &'static str;
58
59 fn empty_options() -> Self::OptionsBuilder;
61
62 fn add_option(builder: &mut Self::OptionsBuilder, name: &str, value: OsString) -> Result<(), GeneratorError>;
64
65 fn finalize_options(builder: Self::OptionsBuilder) -> Result<Self::Options, GeneratorError>;
67
68 fn generate<Output: for<'output> OutputHandler<'output>>(model: &model::Verilization, options: Self::Options, output: &mut Output) -> Result<(), GeneratorError>;
70
71}
72
73pub trait LanguageHandler {
74 type Result;
75 fn run<Lang: Language>(&mut self) -> Self::Result;
76}
77
78pub trait LanguageRegistry : Sized {
79 fn has_language(&self, lang_name: &str) -> bool;
80 fn handle_language<Handler: LanguageHandler>(&self, lang_name: &str, handler: &mut Handler) -> Option<Handler::Result>;
81 fn each_language<Handler: LanguageHandler>(&self, handler: &mut Handler) -> Vec<Handler::Result>;
82
83 fn add_language<Lang: Language>(self) -> LanguageRegistryCons<Lang, Self> {
84 LanguageRegistryCons {
85 prev: self,
86 dummy_lang: PhantomData {},
87 }
88 }
89}
90
91pub struct EmptyLanguageRegistry {}
92pub struct LanguageRegistryCons<Lang: Language, Prev: LanguageRegistry> {
93 prev: Prev,
94 dummy_lang: PhantomData<Lang>,
95}
96
97pub fn language_registry_new() -> EmptyLanguageRegistry {
98 EmptyLanguageRegistry {}
99}
100
101impl LanguageRegistry for EmptyLanguageRegistry {
102 fn has_language(&self, _lang_name: &str) -> bool {
103 false
104 }
105
106 fn handle_language<Handler: LanguageHandler>(&self, _lang_name: &str, _handler: &mut Handler) -> Option<Handler::Result> {
107 None
108 }
109
110 fn each_language<Handler: LanguageHandler>(&self, _handler: &mut Handler) -> Vec<Handler::Result> {
111 Vec::new()
112 }
113}
114
115impl <Lang: Language, Prev: LanguageRegistry> LanguageRegistry for LanguageRegistryCons<Lang, Prev> {
116 fn has_language(&self, lang_name: &str) -> bool {
117 lang_name == Lang::name() || self.prev.has_language(lang_name)
118 }
119
120 fn handle_language<Handler: LanguageHandler>(&self, lang_name: &str, handler: &mut Handler) -> Option<Handler::Result> {
121 if lang_name == Lang::name() {
122 Some(handler.run::<Lang>())
123 }
124 else {
125 self.prev.handle_language(lang_name, handler)
126 }
127 }
128
129 fn each_language<Handler: LanguageHandler>(&self, handler: &mut Handler) -> Vec<Handler::Result> {
130 let mut results = self.prev.each_language(handler);
131 results.push(handler.run::<Lang>());
132 results
133 }
134}
135