Compare commits

...

3 commits

53 changed files with 1347 additions and 741 deletions

View file

@ -2,9 +2,5 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/core_stdlib" vcs="Git" />
<mapping directory="$PROJECT_DIR$/package-manager" vcs="Git" />
<mapping directory="$PROJECT_DIR$/package-manager-server" vcs="Git" />
<mapping directory="$PROJECT_DIR$/runtime" vcs="Git" />
</component> </component>
</project> </project>

View file

@ -19,7 +19,7 @@ semver = "1.0.18"
blake3 = "1.4.1" blake3 = "1.4.1"
lz4_flex = "0.11.1" lz4_flex = "0.11.1"
lex = "0.6.0" lex = "0.6.0"
snafu = "0.7.5" snafu = { version = "0.7.5", features = ["guide"] }
strum_macros = "0.25.1" strum_macros = "0.25.1"
strum = { version = "0.25.0", features = ["derive"] } strum = { version = "0.25.0", features = ["derive"] }
downcast-rs = "1.2.0" downcast-rs = "1.2.0"

View file

@ -18,3 +18,7 @@ https://docs.rs/codemap/latest/codemap/
https://www.youtube.com/watch?v=m64SWl9bfvk https://www.youtube.com/watch?v=m64SWl9bfvk
https://www.youtube.com/watch?v=ApHpmA1k73k https://www.youtube.com/watch?v=ApHpmA1k73k
### Optimizing AST parsing and allocation
https://cs.hofstra.edu/~cscccl/rustlr_project/chapter6.html

View file

@ -1,7 +1,4 @@
tag @? namespace dev
namespace examples.full
// Standard Imports
import std::str::StringBounds import std::str::StringBounds
settings { settings {
@ -10,7 +7,7 @@ settings {
} }
@affects=struct protocol @affects=[struct protocol]
settings MailSettings { settings MailSettings {
indexed=true indexed=true
} }
@ -24,16 +21,16 @@ struct Mail {
struct Article { struct Article {
@validators=[StringBounds(min_chars=3 max_chars=32] @validators=[StringBounds(min_chars=3 max_chars=32]
1# title: str title: str
@validators=[StringBounds(min_chars=24 max_chars=412] @validators=[StringBounds(min_chars=24 max_chars=412]
2# content: str content: str
} }
@hidden @hidden
@settings=MailSettings @settings=MailSettings
protocol Mail { protocol Mail {
1# async function send(Mail) async function send(mail: Mail)
} }
@ -44,5 +41,5 @@ protocol Feed {
// Fetches new articles since last fetch // Fetches new articles since last fetch
@flexible async stream @flexible async stream
#timeout=1000ms per_send_timeout=10s cooldown=10s #timeout=1000ms per_send_timeout=10s cooldown=10s
1# function fetch_articles() -> Article[SENT_ARTICLES_MAX] function fetch_articles() -> Article[SENT_ARTICLES_MAX]
} }

View file

@ -3,7 +3,7 @@
// Crate Uses // Crate Uses
use crate::schema::ir::diff::Differ; use crate::schema::ir::diff::Differ;
use crate::schema::ir::frozen::unit::FrozenUnit; use crate::schema::ir::frozen::unit::FrozenUnit;
use crate::schema::ir::compiler::interpreted::primitive::KindValue; use crate::schema::ir::compiler::interpreted::kind_search::KindValue;
// External Uses // External Uses
@ -61,7 +61,7 @@ impl Differ for Document {
if left_value_display != right_value_display { if left_value_display != right_value_display {
self.minor_changes.push( self.minor_changes.push(
format!( format!(
"Constant '{}' default value changed from '{}' to '{}'", name, "Constant '{}' default value changed from '{:?}' to '{:?}'", name,
left_value_display, right_value_display left_value_display, right_value_display
) )
) )

View file

@ -0,0 +1,3 @@
-- https://andrejs-cainikovs.blogspot.com/2009/05/lua-constants.html
-- http://lua-users.org/wiki/ReadOnlyTables

View file

@ -0,0 +1,52 @@
// Standard Uses
// Crate Uses
use crate::schema::ir::frozen::unit::FrozenUnit;
// External Uses
pub(crate) fn frozen_to_code(units: &Vec<FrozenUnit>) -> String {
let mut code = String::new();
let mut code = "// Generated code with Comline compiler and code generator\n\n"
.to_owned();
for unit in units { code += &*unit_to_code(&unit); }
code
}
fn unit_to_code(frozen_unit: &FrozenUnit) -> String {
let mut code = String::new();
use FrozenUnit::*;
match frozen_unit {
Namespace(_) => {}
Import(_) => {}
Constant { docstring, name, kind_value } => {
let (kind_name, kind_value) = kind_value.name_and_value();
code += &*format!("const {name}: {}", kind_name);
if let Some(value) = kind_value {
code += &*format!(" = {value}");
}
code += ";\n";
}
Property { .. } => {}
Parameter { .. } => {}
ExpressionBlock { .. } => {}
Enum { .. } => {}
EnumVariant(_) => {}
Settings { .. } => {}
Struct { .. } => {}
Protocol { .. } => {}
Function { .. } => {}
Error { .. } => {}
Validator { .. } => {}
_ => panic!("Reached forbidden or unimplemented node")
}
code
}

View file

@ -0,0 +1,21 @@
// https://luau-lang.org/
// Relative Modules
pub mod luau;
// Standard Uses
use std::collections::HashMap;
// Crate Uses
use crate::codegen::VersionGenerators;
// External Uses
use once_cell::sync::Lazy;
pub(crate) static GENERATORS: VersionGenerators = Lazy::new(|| {
HashMap::from([
("Luau", luau::frozen_to_code as _)
])
});

View file

@ -1,5 +1,7 @@
// Relative Modules // Relative Modules
pub mod rust; pub(crate) mod rust;
pub(crate) mod luau;
pub(crate) mod python;
// Standard Uses // Standard Uses
use std::collections::HashMap; use std::collections::HashMap;
@ -11,18 +13,25 @@ use crate::schema::ir::frozen::unit::FrozenUnit;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
pub type VersionGenerators = Lazy<HashMap<&'static str, GeneratorFn>>;
pub type GeneratorFn = fn(&Vec<FrozenUnit>) -> String; pub type GeneratorFn = fn(&Vec<FrozenUnit>) -> String;
pub type Generator = (GeneratorFn, &'static str);
static GENERATORS: Lazy<HashMap<&str, GeneratorFn>> = Lazy::new(|| { static LANG_GENERATORS: Lazy<HashMap<&str, (&VersionGenerators, &str)>> = Lazy::new(|| {
HashMap::from([ HashMap::from([
("rust", rust::frozen_unit_to_code as _), ("rust", (&rust::GENERATORS, "rs")),
("luau", (&luau::GENERATORS, "luau")),
("python", (&python::GENERATORS, "py"))
]) ])
}); });
pub fn find_generator(name: &str) -> Option<&GeneratorFn> { pub fn find_generator(name: &str, version: &str) -> Option<(&'static GeneratorFn, &'static str)> {
if !GENERATORS.contains_key(name) { if let Some((lang_generator, extension)) = LANG_GENERATORS.get(name) {
return None if let Some(version_generator) = lang_generator.get(version) {
return Some((version_generator, extension))
} }
};
GENERATORS.get(name) None
} }

View file

@ -0,0 +1,151 @@
// Standard Uses
// Crate Uses
use crate::schema::ir::frozen::unit::{FrozenArgument, FrozenUnit};
use crate::schema::ir::compiler::interpreted::kind_search::KindValue;
// External Uses
use eyre::anyhow;
#[allow(unused)]
pub fn frozen_to_code(units: &Vec<FrozenUnit>) -> String {
let mut code = "\
# Generated code with Comline compiler and code generator\n\n"
.to_owned();
code += "\
import typing\n\
import ctypes\n\
\n\n\
";
for unit in units { code += &*unit_to_code(&unit); }
code
}
#[allow(unused)]
fn unit_to_code(frozen_unit: &FrozenUnit) -> String {
let mut code = String::new();
use FrozenUnit::*;
match frozen_unit {
Namespace(_) => {}
Import(_) => {}
Constant { docstring, name, kind_value } => {
let (kind_name, default_value) = kind_value.name_and_value();
let Ok(kind_py) = from_frozen_kind_to_python_kind(kind_value) else {
panic!("No appropriate kind was found for '{kind_name}'")
};
// Name and kind
code += &*format!("{name}: typing.Final[{kind_py}]");
// Value
if let Some(value) = default_value {
code += &*format!(" = {value}");
}
code += "\n\n";
}
Property { .. } => {}
Parameter { .. } => {}
ExpressionBlock { .. } => {}
Enum { .. } => {}
EnumVariant(_) => {}
Settings { .. } => {}
Struct { .. } => {}
Protocol {
docstring, parameters,
name, functions
} => {
// Async
// TODO: Can we signify assyncness in python protocols, or if its that important, ABCs?
// Associated methods already can be marked "async"
// Class Start
code += &*format!("class {name}(typing.Protocol):\n");
// Functions
for function in functions {
code += &*unit_to_code(function);
}
// Class End
code += "\n";
}
Function {
docstring, name, synchronous,
arguments, returns,
throws
} => {
// Async definition
if !synchronous { code += "async "; }
// Function Start
code += &*format!("\tdef {name}(");
// Arguments
code += "self";
let mut idx = 0;
while idx != arguments.len() {
let FrozenArgument { name, kind }
= arguments.get(idx).unwrap();
let (kind_name, kind_value) = kind.name_and_value();
code += &*format!("{}: {:?}", name, kind_name);
if idx != arguments.len() { code += ", " }
idx += 1;
}
// Arguments End
code += "):\n\t\t...\n\n";
// Returns
// code += format!("-> {}", return)
// Function End
}
Error { .. } => {}
Validator { .. } => {}
_ => panic!("Reached forbidden or unimplemented node")
}
code
}
fn from_frozen_kind_to_python_kind(kind_value: &KindValue) -> eyre::Result<String> {
let kind = match kind_value {
KindValue::Primitive(primitive) => {
let name = primitive.name();
from_frozen_primitive_to_ctypes(name)
.ok_or_else(|| anyhow!("No primitive equivalent found for {name}"))?
}
KindValue::EnumVariant(_, _) => {
todo!()
}
KindValue::Union(_) => {
todo!()
}
KindValue::Namespaced(_, _) => {
todo!()
}
};
Ok(kind)
}
fn from_frozen_primitive_to_ctypes(primitive: &str) -> Option<String> {
let kind = match primitive {
"u8" => "c_uint8",
"u16" => "c_uint16",
_ => { return None }
};
Some(format!("ctypes.{kind}"))
}

View file

@ -0,0 +1,19 @@
// Relative Modules
pub(crate) mod _3_11_0;
// Standard Uses
use std::collections::HashMap;
// Crate Uses
use crate::codegen::VersionGenerators;
// External Uses
use once_cell::sync::Lazy;
pub(crate) static GENERATORS: VersionGenerators = Lazy::new(|| {
HashMap::from([
("3.11.0", _3_11_0::frozen_to_code as _)
])
});

View file

@ -1,102 +0,0 @@
// Standard Uses
// Crate Uses
use crate::schema::ir::frozen::unit::FrozenUnit;
// External Uses
#[allow(unused)]
pub fn frozen_unit_to_code(units: &Vec<FrozenUnit>) -> String {
"".to_owned()
}
/*
fn unit_to_code(frozen_unit: FrozenUnit) -> String {
let mut code = String::new();
use FrozenUnit::*;
match frozen_unit {
Tag(_) => {}
Namespace(_) => {}
Import(_) => {}
Constant { .. } => {}
Property { .. } => {}
Parameter { .. } => {}
ExpressionBlock { .. } => {}
Enum { .. } => {}
EnumVariant(_) => {}
Settings { .. } => {}
Struct { .. } => {}
Protocol { .. } => {}
Function { .. } => {}
Error { .. } => {}
Validator { .. } => {}
_ => panic!("Reached forbidden or unimplemented node")
}
code
}
fn protocol_to_code(unit: FrozenUnit) -> String {
let FrozenUnit::Protocol {
docstring, parameters, name, functions
} = unit else { panic!() };
let mut code = String::new();
// Trait Start
// TODO: Maybe only include async_trait if at least one of the functions need it
code.push_str("#[async_trait]");
code.push_str(&*format!("pub trait {} {{", name));
// Functions
for function in functions {
let FrozenUnit::Function {
docstring, name, synchronous, direction,
arguments, returns, throws
} = function else { panic!() };
let mut fn_code = String::new();
// Async definition (with async_trait)
if !synchronous {
fn_code.push_str("async ");
}
// Fn
fn_code.push_str(&*format!("fn {} (", name));
// Arguments
let mut idx = 0;
while idx != arguments.len() {
let FrozenUnit::Parameter {
name, default_value
} = arguments.get(idx).unwrap();
if argument.id.is_none() {
fn_code.push_str(&*format!("arg{}: {:?}", idx, argument.type_));
if idx != arguments.len() { fn_code.push_str(", ") }
} else {
fn_code.push_str(
&*format!("{}: {:?}", argument.id.clone().unwrap(), argument.type_)
);
if idx != arguments.len() { fn_code.push_str(", ") }
}
idx += 1;
}
// Returns
code.push_str(&*fn_code)
}
// Trait End
code.push_str("}}");
code.to_owned()
}
*/

View file

@ -0,0 +1,169 @@
// Standard Uses
// Crate Uses
use crate::schema::ir::frozen::unit::{FrozenArgument, FrozenUnit};
// External Uses
#[allow(unused)]
pub fn frozen_to_code(units: &Vec<FrozenUnit>) -> String {
let mut code = "// Generated code with Comline compiler and code generator\n\n"
.to_owned();
for unit in units { code += &*unit_to_code(&unit); }
code
}
#[allow(unused)]
fn unit_to_code(frozen_unit: &FrozenUnit) -> String {
let mut code = String::new();
use FrozenUnit::*;
match frozen_unit {
Namespace(_) => {}
Import(_) => {}
Constant { docstring, name, kind_value } => {
let (kind_name, kind_value) = kind_value.name_and_value();
code += &*format!("pub const {name}: {}", kind_name);
if let Some(value) = kind_value {
code += &*format!(" = {value}");
}
code += ";\n\n";
}
Property { .. } => {}
Parameter { .. } => {}
ExpressionBlock { .. } => {}
Enum { .. } => {}
EnumVariant(_) => {}
Settings { .. } => {}
Struct { .. } => {}
Protocol {
docstring, parameters,
name, functions
} => {
// Async
// TODO: Only include async_trait if at least one of the functions needs it
// code += "#[async_trait]\n";
// Trait Start
code += &*format!("pub trait {} {{\n", name);
// Functions
for function in functions {
code += &*unit_to_code(function);
}
// Trait End
code += "\n}\n\n";
}
Function {
docstring, name, synchronous,
arguments, returns,
throws
} => {
code += "\t";
// Async definition (with async_trait)
if !synchronous { code += "async "; }
// Function Start
code += &*format!("fn {} (", name);
code += "&self";
// Arguments
let mut idx = 0;
while idx != arguments.len() {
let FrozenArgument { name, kind }
= arguments.get(idx).unwrap();
let (kind_name, kind_value) = kind.name_and_value();
code += &*format!("{}: {:?}", name, kind_name);
if idx != arguments.len() { code += ", " }
idx += 1;
}
// Arguments End
code += ")";
// Returns
// code += format!("-> {}", return)
// Function End
code += ";\n";
}
Error { .. } => {}
Validator { .. } => {}
_ => panic!("Reached forbidden or unimplemented node")
}
code
}
/*
fn protocol_to_code(unit: FrozenUnit) -> String {
let FrozenUnit::Protocol {
docstring, parameters, name, functions
} = unit else { panic!() };
let mut code = String::new();
// Trait Start
// TODO: Maybe only include async_trait if at least one of the functions need it
code.push_str("#[async_trait]");
code.push_str(&*format!("pub trait {} {{", name));
// Functions
for function in functions {
let FrozenUnit::Function {
docstring, name, synchronous, direction,
arguments, returns, throws
} = function else { panic!() };
let mut fn_code = String::new();
// Async definition (with async_trait)
if !synchronous {
fn_code.push_str("async ");
}
// Fn
fn_code.push_str(&*format!("fn {} (", name));
// Arguments
let mut idx = 0;
while idx != arguments.len() {
let FrozenUnit::Parameter {
name, default_value
} = arguments.get(idx).unwrap();
if argument.id.is_none() {
fn_code.push_str(&*format!("arg{}: {:?}", idx, argument.type_));
if idx != arguments.len() { fn_code.push_str(", ") }
} else {
fn_code.push_str(
&*format!("{}: {:?}", argument.id.clone().unwrap(), argument.type_)
);
if idx != arguments.len() { fn_code.push_str(", ") }
}
idx += 1;
}
// Returns
code.push_str(&*fn_code)
}
// Trait End
code.push_str("}}");
code.to_owned()
}
*/

View file

@ -0,0 +1,19 @@
// Relative Modules
pub(crate) mod _1_7_0;
// Standard Uses
use std::collections::HashMap;
// Crate Uses
use crate::codegen::VersionGenerators;
// External Uses
use once_cell::sync::Lazy;
pub(crate) static GENERATORS: VersionGenerators = Lazy::new(|| {
HashMap::from([
("1.70.0", _1_7_0::frozen_to_code as _)
])
});

View file

@ -1,8 +1,8 @@
#![deny(rust_2018_idioms)]
// Extern // Extern
extern crate pest;
#[macro_use] #[macro_use]
extern crate pest_derive; extern crate pest_derive;
extern crate serde;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate rmp_serde as rmps; extern crate rmp_serde as rmps;

View file

@ -13,7 +13,7 @@ use crate::project::idl::constants::CONGREGATION_EXTENSION;
use crate::project::ir::interpreter::Interpreter as ProjectInterpreter; use crate::project::ir::interpreter::Interpreter as ProjectInterpreter;
use crate::project::ir::compiler::Compile; use crate::project::ir::compiler::Compile;
use crate::project::ir::{compiler, diff, frozen}; use crate::project::ir::{compiler, diff, frozen};
use crate::project::ir::frozen::{FrozenUnit, FrozenWhole}; use crate::project::ir::frozen::FrozenUnit;
use crate::project::ir::frozen::meta::Index; use crate::project::ir::frozen::meta::Index;
use crate::project::ir::context::ProjectContext; use crate::project::ir::context::ProjectContext;
use crate::schema::{idl, ir}; use crate::schema::{idl, ir};
@ -38,45 +38,43 @@ pub fn build(path: &Path) -> Result<()> {
let latest_frozen = frozen::loader::from_latest_frozen(&frozen_path); let latest_frozen = frozen::loader::from_latest_frozen(&frozen_path);
let compiled_project = ProjectInterpreter::from_origin(config_path); let (mut compiled_project, frozen)
= ProjectInterpreter::from_origin(config_path)?;
// TODO: Check integrity of the frozen contents, if they are valid, if something is broken, etc // TODO: Check integrity of the frozen contents, if they are valid, if something is broken, etc
if let Some(latest_frozen) = latest_frozen { if let Some(latest_frozen) = latest_frozen {
diff::differ( diff::differ(&latest_frozen, &frozen, true, true);
&latest_frozen, &compiled_project,
true, true
);
} }
let mut project_ctx = RefCell::borrow_mut(&compiled_project.0); let schema_paths = frozen::schema_paths(&frozen);
for relative in frozen::schema_paths(&compiled_project.1) { for relative in schema_paths {
let concrete = format!("{:}/{}", path.to_str().unwrap(), relative); let concrete = format!("{:}/{}", path.to_str().unwrap(), relative);
let concrete_path = Path::new(&concrete); let concrete_path = Path::new(&concrete);
let unit = idl::parser_new::from_path(concrete_path)?; let unit = idl::parser_new::from_path(concrete_path)?;
let context = Rc::new(RefCell::new( let context = ir::context::SchemaContext::with_project_and_main(
ir::context::SchemaContext::with_project_and_main( unit, concrete_path.file_stem().unwrap().to_str().unwrap().to_owned()
unit, compiled_project.0.clone() );
)
));
project_ctx.add_schema_context(context.clone()); compiled_project.add_schema_context(
Rc::new(RefCell::new(context))
);
} }
compiler::interpret::interpret_context(&project_ctx)?; compiler::interpret::interpret_context(&mut compiled_project)?;
// We drop here since we should not need mutability anymore generate_code_for_targets(&mut compiled_project, &frozen, path)?;
drop(project_ctx);
generate_code_for_targets(&compiled_project).unwrap();
Ok(()) Ok(())
} }
pub fn generate_code_for_targets(compiled_project: &FrozenWhole) -> Result<()> { pub fn generate_code_for_targets<'a>(
for item in compiled_project.1.iter() { compiled_project: &'a mut ProjectContext<'a>, frozen_units: &'a Vec<FrozenUnit>,
base_path: &Path
) -> Result<()> {
for item in frozen_units.iter() {
match item { match item {
FrozenUnit::CodeGeneration(details) => { FrozenUnit::CodeGeneration(details) => {
let Some((name, version)) = details.name.split_once("#") else { let Some((name, version)) = details.name.split_once("#") else {
@ -90,19 +88,19 @@ pub fn generate_code_for_targets(compiled_project: &FrozenWhole) -> Result<()> {
}; };
let path = resolve_path_query(&details.generation_path, args).unwrap(); let path = resolve_path_query(&details.generation_path, args).unwrap();
let path = Path::new(&path); let path = base_path.join(path);
let generator = codegen::find_generator(name); let Some((gen_fn, extension)) =
codegen::find_generator(name, version) else
if generator.is_none() { {
panic!( panic!(
"No generator found for language named {} with version {}", "No generator found for language named '{}' with version '{}'",
name, version name, version
) )
} };
generate_code_for_context( generate_code_for_context(
&compiled_project.0.borrow(), generator, &path &compiled_project, gen_fn, extension, &path
)?; )?;
}, },
_ => {} _ => {}
@ -131,18 +129,24 @@ pub fn resolve_path_query(query: &Option<String>, args: Args) -> Result<String,
} }
} }
pub fn generate_code_for_context( #[allow(unused)]
context: &ProjectContext, generator: Option<&GeneratorFn>, target_path: &Path pub fn generate_code_for_context<'a>(
context: &ProjectContext<'a>,
generator: &GeneratorFn, extension: &str,
target_path: &Path
) -> Result<()> { ) -> Result<()> {
std::fs::create_dir_all(target_path)?;
for schema_context in context.schema_contexts.iter() { for schema_context in context.schema_contexts.iter() {
let ctx = schema_context.borrow(); let schema_ctx = schema_context.borrow();
let frozen_schema = ctx.frozen_schema.as_ref().unwrap(); let frozen_schema = schema_ctx.frozen_schema.as_ref().unwrap();
let file_path = target_path.join(
format!("{}.{}", &schema_ctx.name, extension)
);
let mut code = "Generated code with Comline compiler".to_owned(); let code = &*generator(frozen_schema);
code += &*generator.unwrap()(frozen_schema); std::fs::write(file_path, code).unwrap();
std::fs::write(target_path, code).unwrap();
} }
Ok(()) Ok(())

View file

@ -49,7 +49,7 @@ pub fn parse_source(source: String, name: String) -> Result<SourcedWhole> {
Ok((codemap, units)) Ok((codemap, units))
} }
pub fn parse_inner(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> { pub fn parse_inner(pair: Pair<'_, Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> {
match pair.as_rule() { match pair.as_rule() {
Rule::congregation => { Rule::congregation => {
let span = pair.as_span(); let span = pair.as_span();
@ -96,7 +96,7 @@ pub fn parse_inner(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit>
#[allow(unused)] #[allow(unused)]
fn parse_assignment(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<AssignmentUnit> { fn parse_assignment(pair: Pair<'_, Rule>, file: &Arc<FileMap>) -> Result<AssignmentUnit> {
let unit = match pair.as_rule() { let unit = match pair.as_rule() {
Rule::number => { Rule::number => {
Ok(AssignmentUnit::Number(pair.as_str().parse().unwrap())) Ok(AssignmentUnit::Number(pair.as_str().parse().unwrap()))
@ -156,7 +156,7 @@ fn parse_assignment(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<AssignmentU
} }
fn parse_list_item(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<ListItem> { fn parse_list_item(pair: Pair<'_, Rule>, file: &Arc<FileMap>) -> Result<ListItem> {
let span = pair.as_span(); let span = pair.as_span();
let item_span = file.insert_span(span.start(), span.end()); let item_span = file.insert_span(span.start(), span.end());

View file

@ -1,27 +1,29 @@
// Standard Uses // Standard Uses
use std::cell::RefMut;
use std::rc::Rc;
// Crate Uses // Crate Uses
use crate::project::ir::context::ProjectContext; use crate::project::ir::context::ProjectContext;
use crate::schema::ir::compiler::interpreted::interpreter; use crate::schema::ir::compiler::interpreter::{meta_stage, object_stage};
use crate::schema::ir::compiler::interpreter::meta_stage;
// External Uses // External Uses
use eyre::{anyhow, Result}; use eyre::{anyhow, Result};
pub fn interpret_context(project_context: &RefMut<ProjectContext>) -> Result<()> { pub fn interpret_context(project_context: &ProjectContext<'_>) -> Result<()> {
for schema_context in project_context.schema_contexts.iter() { for schema_context in project_context.schema_contexts.iter() {
meta_stage::compile_schema_metadata(schema_context, project_context) meta_stage::compile_schema_metadata(
.map_err(|e| anyhow!("{}", e))?; Rc::clone(&schema_context),
project_context
).map_err(|e| anyhow!("{}", e))?;
} }
/*
for schema_context in project_context.schema_contexts.iter() { for schema_context in project_context.schema_contexts.iter() {
interpreter::interpret_context(schema_context, project_context) object_stage::compile_schema(
.map_err(|e| anyhow!("{}", e))?; Rc::clone(&schema_context),
project_context
).map_err(|e| anyhow!("{}", e))?;
} }
*/
Ok(()) Ok(())
} }

View file

@ -11,16 +11,13 @@ use snafu::Snafu;
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
#[snafu(visibility(pub(crate)))] #[snafu(visibility(pub(crate)))]
pub enum CompileError { pub enum CompileError {
// #[strum(props(Id="2"))]
#[snafu(display("Found namespace '{target}' when its already declared in '{origin}'"))] #[snafu(display("Found namespace '{target}' when its already declared in '{origin}'"))]
Namespace { origin: String, target: String }, Namespace { origin: String, target: String } = 0,
// #[strum(props(Id="2"))]
#[snafu(display("Spec version was not assigned'"))] #[snafu(display("Spec version was not assigned'"))]
// SpecVersionNotTold { source: Box<dyn std::error::Error + Send + Sync> } // SpecVersionNotTold { source: Box<dyn std::error::Error + Send + Sync> }
SpecVersionNotTold { source: io::Error }, SpecVersionNotTold { source: io::Error },
// #[strum(props(Id="2"))]
#[snafu(display("Schema paths list is empty, at least one schema is required'"))] #[snafu(display("Schema paths list is empty, at least one schema is required'"))]
// SpecVersionNotTold { source: Box<dyn std::error::Error + Send + Sync> } // SpecVersionNotTold { source: Box<dyn std::error::Error + Send + Sync> }
SchemaPathsEmpty, SchemaPathsEmpty,
@ -36,4 +33,4 @@ impl From<CompileError> for Error {
} }
*/ */
pub type CompileResult<T, E = CompileError> = std::result::Result<T, E>; pub type CompileResult<T, E = CompileError> = Result<T, E>;

View file

@ -5,8 +5,8 @@ use std::rc::Rc;
// Crate Uses // Crate Uses
use crate::project::idl::ast::{SourcedWhole as ProjectSourcedWhole}; use crate::project::idl::ast::{SourcedWhole as ProjectSourcedWhole};
use crate::schema::ir::context::SchemaContext;
use crate::schema::idl::ast::unit::{ASTUnit, Details}; use crate::schema::idl::ast::unit::{ASTUnit, Details};
use crate::schema::ir::context::SchemaContext;
// External Uses // External Uses
@ -17,18 +17,17 @@ pub enum Origin {
Disk(PathBuf) Disk(PathBuf)
} }
#[derive(Clone)] pub struct ProjectContext<'a> {
pub struct ProjectContext {
pub origin: Origin, pub origin: Origin,
pub config: ProjectSourcedWhole, pub config: ProjectSourcedWhole,
pub schema_contexts: Vec<Rc<RefCell<SchemaContext>>>, pub schema_contexts: Vec<Rc<RefCell<SchemaContext<'a>>>>,
pub relative_projects: Vec<Rc<ProjectContext>>, pub relative_projects: Vec<ProjectContext<'a>>,
} }
#[allow(unused)] #[allow(unused)]
impl ProjectContext { impl<'a> ProjectContext<'a> {
pub fn with_config_origin(origin: Origin, config: ProjectSourcedWhole) -> Self { pub fn with_config_origin(origin: Origin, config: ProjectSourcedWhole) -> Self {
Self { Self {
origin, config, origin, config,
@ -47,15 +46,15 @@ impl ProjectContext {
pub(crate) fn add_relative_project(mut self, sourced: ProjectSourcedWhole) { pub(crate) fn add_relative_project(mut self, sourced: ProjectSourcedWhole) {
self.relative_projects.push( self.relative_projects.push(
Rc::from(Self::with_config(sourced)) Self::with_config(sourced)
) )
} }
pub(crate) fn add_relative_project_context(mut self, context: Rc<ProjectContext>) { pub(crate) fn add_relative_project_context(mut self, context: Rc<ProjectContext<'a>>) {
todo!() todo!()
} }
pub(crate) fn add_schema_context(&mut self, context: Rc<RefCell<SchemaContext>>) { pub(crate) fn add_schema_context(&mut self, context: Rc<RefCell<SchemaContext<'a>>>) {
self.schema_contexts.push(context); self.schema_contexts.push(context);
} }
@ -63,11 +62,11 @@ impl ProjectContext {
todo!() todo!()
} }
pub(crate) fn find_schema_by_import(&self, import: &str) -> Option<&Rc<RefCell<SchemaContext>>> { pub(crate) fn find_schema_by_import(&self, import: &str)
-> Option<&Rc<RefCell<SchemaContext<'a>>>>
{
for schema_context in self.schema_contexts.iter() { for schema_context in self.schema_contexts.iter() {
let ctx = schema_context.borrow(); let units = &schema_context.borrow().schema.1;
let units = &ctx.schema.1;
if let Some(unit) = units.find_namespace() { if let Some(unit) = units.find_namespace() {
if let ASTUnit::Namespace(_, namespace) = &unit.1 { if let ASTUnit::Namespace(_, namespace) = &unit.1 {
if namespace == import { if namespace == import {
@ -80,6 +79,23 @@ impl ProjectContext {
None None
} }
/*
pub(crate) fn find_schema_by_import(&self, import: &str)
-> Option<&Rc<RefCell<SchemaContext<'a>>>>
{
for schema_context in self.schema_contexts.iter() {
let schema_ctx = schema_context.borrow();
let state = schema_ctx.compile_state.borrow();
if let Some(state) = &state.namespace {
return Some(schema_context)
}
}
None
}
*/
/* /*
pub(crate) fn find_whole_unit_by_import(&self, import: &str) -> Option<&WholeUnit> { pub(crate) fn find_whole_unit_by_import(&self, import: &str) -> Option<&WholeUnit> {
if self.include_stdlib { if self.include_stdlib {
@ -98,7 +114,9 @@ impl ProjectContext {
} }
*/ */
pub(crate) fn find_relative_project_context(&self, import: &str) -> Option<&ProjectContext> { pub(crate) fn find_relative_project_context(&self, import: &str)
-> Option<&ProjectContext<'a>>
{
todo!() todo!()
} }

View file

@ -6,13 +6,13 @@ pub mod versioning;
use std::fmt::Debug; use std::fmt::Debug;
// Crate Uses // Crate Uses
use crate::autodoc::document::Document;
use crate::project::ir::frozen::{Dependency, FrozenUnit, FrozenWhole}; use crate::project::ir::frozen::{Dependency, FrozenUnit, FrozenWhole};
use crate::autodoc::document::Document;
use crate::project::ir::diff::versioning::Versioning; use crate::project::ir::diff::versioning::Versioning;
// External Uses // External Uses
use semver::Version;
use downcast_rs::{Downcast, impl_downcast}; use downcast_rs::{Downcast, impl_downcast};
use semver::Version;
pub trait Differ: Downcast + Debug { pub trait Differ: Downcast + Debug {
@ -23,18 +23,19 @@ pub trait Differ: Downcast + Debug {
// fn on_assignment_changed(&self, old: AssignmentUnit, new: AssignmentUnit); // fn on_assignment_changed(&self, old: AssignmentUnit, new: AssignmentUnit);
fn differ( #[allow(unused)]
&self, previous: &Vec<FrozenUnit>, next: &FrozenWhole, fn differ<'a>(
&self, previous: &Vec<FrozenUnit>, next: &FrozenWhole<'a>,
document_gen: bool, auto_version: bool document_gen: bool, auto_version: bool
) { ) {
differ(previous, next, document_gen, auto_version) // differ(previous, next, document_gen, auto_version)
} }
} }
impl_downcast!(Differ); impl_downcast!(Differ);
#[allow(unused)] #[allow(unused)]
pub fn differ( pub fn differ(
previous: &Vec<FrozenUnit>, next: &FrozenWhole, previous: &Vec<FrozenUnit>, next: &Vec<FrozenUnit>,
document_gen: bool, auto_version: bool document_gen: bool, auto_version: bool
) { ) {
let mut previous_version = versioning::version_from(previous).unwrap_or( let mut previous_version = versioning::version_from(previous).unwrap_or(
@ -55,13 +56,13 @@ pub fn differ(
#[allow(unused)] #[allow(unused)]
pub fn match_differ( pub fn match_differ(
mut listeners: &mut Vec<Box<dyn Differ>>, mut listeners: &mut Vec<Box<dyn Differ>>,
previous: &Vec<FrozenUnit>, next: &FrozenWhole previous: &Vec<FrozenUnit>, next: &Vec<FrozenUnit>
) { ) {
for node in previous { for node in previous {
use FrozenUnit::*; use FrozenUnit::*;
match node { match node {
Namespace(_) => { Namespace(_) => {
search_other(node, &next.1).map(|l| { search_other(node, &next).map(|l| {
let Namespace(old) = node else { panic!() }; let Namespace(old) = node else { panic!() };
let Namespace(new) = l else { panic!() }; let Namespace(new) = l else { panic!() };
@ -73,7 +74,7 @@ pub fn match_differ(
}); });
} }
SpecificationVersion(_) => { SpecificationVersion(_) => {
search_other(node, &next.1).map(|l| { search_other(node, &next).map(|l| {
let SpecificationVersion(old) = node else { panic!() }; let SpecificationVersion(old) = node else { panic!() };
let SpecificationVersion(new) = l else { panic!() }; let SpecificationVersion(new) = l else { panic!() };

View file

@ -9,7 +9,7 @@ use eyre::Result;
#[allow(unused)] #[allow(unused)]
pub fn from_frozen_origin(path: &Path) -> Option<FrozenWhole> { pub fn from_frozen_origin(path: &Path) -> Option<FrozenWhole<'_>> {
// let context = from_frozen_objects(&project_path); // let context = from_frozen_objects(&project_path);
todo!() todo!()

View file

@ -3,9 +3,6 @@ pub mod loader;
pub mod meta; pub mod meta;
// Standard Uses // Standard Uses
use std::rc::Rc;
use std::cell::RefCell;
use std::slice::Iter; use std::slice::Iter;
use std::iter::FilterMap; use std::iter::FilterMap;
@ -15,7 +12,7 @@ use crate::project::ir::context::ProjectContext;
// External Uses // External Uses
pub type FrozenWhole = (Rc<RefCell<ProjectContext>>, Vec<FrozenUnit>); pub type FrozenWhole<'a> = (ProjectContext<'a>, Vec<FrozenUnit>);
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
@ -50,7 +47,7 @@ pub struct PublishTarget {
} }
pub fn schema_paths(units: &Vec<FrozenUnit>) pub fn schema_paths(units: &Vec<FrozenUnit>)
-> FilterMap<Iter<FrozenUnit>, fn(&FrozenUnit) -> Option<&str>> -> FilterMap<Iter<'_, FrozenUnit>, fn(&FrozenUnit) -> Option<&str>>
{ {
units.iter().filter_map(|unit| { units.iter().filter_map(|unit| {
match unit { match unit {

View file

@ -2,18 +2,17 @@
// Crate Uses // Crate Uses
use crate::project::idl::ast::{AssignmentUnit, ASTUnit, DictKeyValue, ListItem}; use crate::project::idl::ast::{AssignmentUnit, ASTUnit, DictKeyValue, ListItem};
use crate::project::ir::compiler::report::CompileError;
use crate::project::ir::context::ProjectContext; use crate::project::ir::context::ProjectContext;
use crate::project::ir::frozen::{FrozenUnit, FrozenWhole, LanguageDetails, PublishTarget}; use crate::project::ir::frozen::{FrozenUnit, FrozenWhole, LanguageDetails, PublishTarget};
use crate::report::ReportDetails;
use crate::utils::codemap::Span; use crate::utils::codemap::Span;
// External Uses // External Uses
#[allow(unused)] #[allow(unused)]
pub fn interpret_node_into_frozen(context: &ProjectContext, node: &ASTUnit) pub fn interpret_node_into_frozen<'a>(
-> Result<Vec<FrozenUnit>, ReportDetails<CompileError>> context: &ProjectContext<'a>, node: &ASTUnit
) -> Result<Vec<FrozenUnit>, Box<dyn snafu::Error>>
{ {
// use crate::project::idl::ast::ASTUnit::*; // use crate::project::idl::ast::ASTUnit::*;
match node { match node {
@ -27,9 +26,9 @@ pub fn interpret_node_into_frozen(context: &ProjectContext, node: &ASTUnit)
} }
} }
pub fn interpret_assignment( pub fn interpret_assignment<'a>(
context: &ProjectContext, name: &(Span, String), node: &(Span, AssignmentUnit) context: &ProjectContext<'a>, name: &(Span, String), node: &(Span, AssignmentUnit)
) -> Result<Vec<FrozenUnit>, ReportDetails<CompileError>> { ) -> Result<Vec<FrozenUnit>, Box<dyn snafu::Error>> {
let result = match &*name.1 { let result = match &*name.1 {
"specification_version" => { "specification_version" => {
let AssignmentUnit::Number(version) = &node.1 else { let AssignmentUnit::Number(version) = &node.1 else {
@ -84,7 +83,7 @@ pub fn interpret_assignment(
} }
fn interpret_assignment_code_generation(items: &Vec<DictKeyValue>) fn interpret_assignment_code_generation(items: &Vec<DictKeyValue>)
-> Result<Vec<FrozenUnit>, ReportDetails<CompileError>> -> Result<Vec<FrozenUnit>, Box<dyn snafu::Error>>
{ {
let mut languages = vec![]; let mut languages = vec![];
@ -144,7 +143,7 @@ fn interpret_assignment_code_generation(items: &Vec<DictKeyValue>)
} }
fn interpret_assigment_publish_targets(items: &Vec<DictKeyValue>) fn interpret_assigment_publish_targets(items: &Vec<DictKeyValue>)
-> Result<Vec<FrozenUnit>, ReportDetails<CompileError>> -> Result<Vec<FrozenUnit>, Box<dyn snafu::Error>>
{ {
let mut targets = vec![]; let mut targets = vec![];
@ -202,9 +201,9 @@ fn interpret_assigment_publish_targets(items: &Vec<DictKeyValue>)
} }
#[allow(unused)] #[allow(unused)]
pub fn into_frozen_whole( pub fn into_frozen_whole<'a>(
context: &ProjectContext, interpreted: Vec<FrozenUnit> context: &'a ProjectContext<'a>, interpreted: Vec<FrozenUnit>
) -> Result<FrozenWhole, ReportDetails<CompileError>> ) -> Result<FrozenWhole<'a>, Box<dyn snafu::Error>>
{ {
todo!() todo!()
// Ok((Rc::from(context), interpreted)) // Ok((Rc::from(context), interpreted))

View file

@ -1,22 +1,18 @@
// Standard Uses // Standard Uses
use std::cell::RefCell;
use std::rc::Rc;
// Crate Uses // Crate Uses
use crate::project::ir::context::ProjectContext; use crate::project::ir::context::ProjectContext;
use crate::project::ir::frozen::{FrozenUnit, FrozenWhole}; use crate::project::ir::frozen::FrozenUnit;
use crate::project::ir::compiler::report::CompileError;
use crate::project::ir::interpreter::freezing; use crate::project::ir::interpreter::freezing;
use crate::report::ReportDetails;
// External Uses // External Uses
#[allow(unused)] #[allow(unused)]
pub fn interpret_context(context: ProjectContext) pub fn interpret_context<'a>(mut context: &ProjectContext<'a>)
-> Result<FrozenWhole, ReportDetails<CompileError>> -> Result<Vec<FrozenUnit>, Box<dyn snafu::Error>>
{ {
let mut interpreted: Vec<FrozenUnit> = vec![]; let mut interpreted = vec![];
for node in &context.config.1 { for node in &context.config.1 {
let file = context.config.0.files().first().unwrap(); let file = context.config.0.files().first().unwrap();
@ -27,6 +23,6 @@ pub fn interpret_context(context: ProjectContext)
); );
} }
Ok((Rc::new(RefCell::new(context)), interpreted)) Ok(interpreted)
// freezing::into_frozen_whole(&context, interpreted) // freezing::into_frozen_whole(&context, interpreted)
} }

View file

@ -7,24 +7,25 @@ pub mod freezing;
use std::path::Path; use std::path::Path;
// Crate Uses // Crate Uses
use crate::project;
use crate::project::idl::parser_new; use crate::project::idl::parser_new;
use crate::project::idl::ast::{ASTUnit, SourcedWhole}; use crate::project::idl::ast::{ASTUnit, SourcedWhole};
use crate::project::ir::context::{Origin, ProjectContext}; use crate::project::ir::context::{Origin, ProjectContext};
use crate::project::ir::frozen::FrozenWhole; use crate::project::ir::frozen::FrozenUnit;
use crate::project::ir::compiler::Compile; use crate::project::ir::compiler::Compile;
// External Uses // External Uses
use eyre::{anyhow, Result};
#[allow(unused)] #[allow(unused)]
pub struct Interpreter { pub struct Interpreter<'a> {
context: ProjectContext context: ProjectContext<'a>
} }
#[allow(unused)] #[allow(unused)]
impl Compile for Interpreter { impl<'a> Compile for Interpreter<'a> {
type Output = FrozenWhole; // type Output = Result<(RefCell<ProjectContext<'a>>, Vec<FrozenUnit>)>;
type Output = Result<(ProjectContext<'a>, Vec<FrozenUnit>)>;
fn from_ast(ast: Vec<ASTUnit>) -> Self::Output { fn from_ast(ast: Vec<ASTUnit>) -> Self::Output {
todo!() todo!()
@ -32,8 +33,10 @@ impl Compile for Interpreter {
fn from_sourced_whole(sourced: SourcedWhole) -> Self::Output { fn from_sourced_whole(sourced: SourcedWhole) -> Self::Output {
let context = ProjectContext::with_config(sourced); let context = ProjectContext::with_config(sourced);
let frozen = interpret::interpret_context(&context)
.map_err(|e| anyhow!("{:?}", e))?;
interpret::interpret_context(context).unwrap() Ok((context, frozen))
} }
fn from_source(source: &str) -> Self::Output { fn from_source(source: &str) -> Self::Output {
@ -47,11 +50,14 @@ impl Compile for Interpreter {
} }
fn from_origin(origin: &Path) -> Self::Output { fn from_origin(origin: &Path) -> Self::Output {
let sourced = project::idl::parser_new::from_path(&origin).unwrap(); let sourced = parser_new::from_path(&origin).unwrap();
let context = ProjectContext::with_config_origin( let context = ProjectContext::with_config_origin(
Origin::Disk(origin.to_path_buf()), sourced Origin::Disk(origin.to_path_buf()), sourced
); );
let frozen = interpret::interpret_context(&context)
.map_err(|e| anyhow!("{:?}", e))?;
interpret::interpret_context(context).unwrap() // Ok((RefCell::new(context), frozen))
Ok((context, frozen))
} }
} }

View file

@ -1,20 +1,15 @@
// Standard Uses // Standard Uses
// Crate Uses // Crate Uses
use crate::schema::ir::compiler::report::CompileWarning;
use crate::project::idl::ast::AssignmentUnit;
use crate::project::ir::compiler::report::CompileResult;
use crate::project::ir::frozen::Dependency;
use crate::report::ReportDetails;
// External Uses // External Uses
/*
#[allow(unused)] #[allow(unused)]
pub fn report_errors( pub fn report_errors(
spec_version: Option<u32>, schema_paths: Option<Vec<String>>, spec_version: Option<u32>, schema_paths: Option<Vec<String>>,
dependencies: Option<Vec<Dependency>>, assignments: Vec<AssignmentUnit> dependencies: Option<Vec<Dependency>>, assignments: Vec<AssignmentUnit>
) -> CompileResult<()> { ) -> Result<(), dyn snafu::Error> {
// let mut errors = vec![]; // let mut errors = vec![];
// let spec_version = spec_version.context(report::SpecVersionNotToldSnafu); // let spec_version = spec_version.context(report::SpecVersionNotToldSnafu);
@ -48,3 +43,4 @@ pub fn report_warnings(
warnings warnings
} }
*/

View file

@ -1,32 +1,35 @@
// Standard Uses // Standard Uses
use std::marker::PhantomData; use std::cell::Ref;
use std::ops::Range;
// Local Uses // Crate Uses
use crate::schema::ir::context::SchemaContext; use crate::schema::ir::context::SchemaContext;
use crate::schema::ir::compiler::report::CompileError;
use crate::utils::codemap::Span; use crate::utils::codemap::Span;
// External Uses // External Uses
use ariadne::Color;
#[derive(Debug)] #[derive(Debug)]
pub struct ReportDetails<T> { pub struct ReportDetails {
// pub id: u16, pub line: Range<usize>,
// pub message: String, pub pos: Range<usize>
pub(crate) phantom: PhantomData<T>, // pub kind: T,
pub span: Option<Span>
} }
#[allow(unused)] impl ReportDetails {
impl<T> ReportDetails<T> { pub(crate) fn fetch(
fn code(&self) -> u8 { schema_context: &Ref<'_, SchemaContext<'_>>, span: &Span
0 ) -> Option<Self> {
let pos = schema_context.schema.0.files().first()
.unwrap().range_of(*span).unwrap();
Some(Self { line: Default::default(), pos })
} }
} }
/*
#[allow(unused)] #[allow(unused)]
pub fn report_errors(context: SchemaContext, errors: Vec<ReportDetails<CompileError>>) { pub fn report_errors<'a>(context: SchemaContext<'_>, errors: Vec<ReportDetails<CompileError>>) {
let out = Color::Fixed(81); let out = Color::Fixed(81);
/* /*
@ -47,8 +50,9 @@ pub fn report_errors(context: SchemaContext, errors: Vec<ReportDetails<CompileEr
#[allow(unused)] #[allow(unused)]
pub fn report_warnings(context: SchemaContext, warnings: Vec<ReportDetails<CompileError>>) { pub fn report_warnings(context: SchemaContext<'_>, warnings: Vec<ReportDetails<CompileError>>) {
todo!() todo!()
} }
*/

View file

@ -1,5 +1,6 @@
// Standard Uses // Standard Uses
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell;
// Local Uses // Local Uses
use crate::utils::codemap::{CodeMap, Span}; use crate::utils::codemap::{CodeMap, Span};
@ -78,7 +79,9 @@ pub enum ASTUnit {
throws: Vec<(Span, String)> throws: Vec<(Span, String)>
}, },
Argument { Argument {
name: Option<(Span, String)>, // TODO: Having optional names might not be a good thing // TODO: Having optional names might not be a good thing, think about it
// name: Option<(Span, String)>,
name: (Span, String),
kind: (Span, String) kind: (Span, String)
}, },
Error { Error {
@ -105,6 +108,8 @@ pub enum ASTUnit {
} }
} }
#[allow(unused)]
pub(crate) fn namespace(units: &Vec<SpannedUnit>) -> &String { pub(crate) fn namespace(units: &Vec<SpannedUnit>) -> &String {
let mut namespace: Option<&String> = None; let mut namespace: Option<&String> = None;
@ -137,7 +142,8 @@ pub type SourcedWholeRc = (CodeMap, Vec<Rc<SpannedUnit>>);
pub trait Details<'a> { pub trait Details<'a> {
fn find_namespace(&self) -> Option<&'a SpannedUnit>; fn find_namespace(&self) -> Option<&'a SpannedUnit> { todo!() }
fn find_namespace_rc(&self) -> Option<&'a Rc<RefCell<SpannedUnit>>> { todo!() }
} }
impl<'a> Details<'a> for &'a Vec<SpannedUnit> { impl<'a> Details<'a> for &'a Vec<SpannedUnit> {
@ -165,3 +171,17 @@ impl<'a> Details<'a> for &'a Vec<Rc<SpannedUnit>> {
None None
} }
} }
impl<'a> Details<'a> for &'a Vec<Rc<RefCell<SpannedUnit>>> {
fn find_namespace_rc(&self) -> Option<&'a Rc<RefCell<SpannedUnit>>> {
for unit in self.iter() {
match unit.borrow().1 {
ASTUnit::Namespace(_, _) => return Some(unit),
_ => {}
}
}
None
}
}

View file

@ -134,7 +134,7 @@ protocol = {
~ "{" ~ WS? ~ function* ~ WS? ~ "}" ~ "{" ~ WS? ~ function* ~ WS? ~ "}"
} }
function = { function = {
WS? ~ property* WS? ~ docstring? ~ property*
~ (index ~ WS? ~ "#" ~ WS?)? ~ (index ~ WS? ~ "#" ~ WS?)?
~ (asynchronous ~ WS?)? ~ (asynchronous ~ WS?)?
~ (direction ~ WS?)? ~ (direction ~ WS?)?
@ -143,6 +143,7 @@ function = {
~ (WS? ~ "->" ~ WS? ~ returns+)? ~ (WS? ~ "->" ~ WS? ~ returns+)?
// ~ (WS? ~ ":" ~ WS? ~ parameter+)? // ~ (WS? ~ ":" ~ WS? ~ parameter+)?
~ (WS? ~ "!" ~ WS? ~ throws)? ~ (WS? ~ "!" ~ WS? ~ throws)?
~ ";"
} }
direction = { "client" | "server" } direction = { "client" | "server" }
@ -153,15 +154,15 @@ argument = {
~ WS? ~ WS?
} }
returns = { ","? ~ WS? ~ (kind) ~ WS? } returns = { ","? ~ WS? ~ (kind) ~ WS? }
parameter = {
WS? ~ id ~ WS? ~ "=" ~ WS? ~ value ~ WS?
}
throws = { throws = {
function_call function_call
} }
// Common Rules // Common Rules
parameter = {
WS? ~ id ~ WS? ~ "=" ~ WS? ~ value ~ WS?
}
property = { property = {
WS? ~ "@" WS? ~ "@"
~ WS? ~ property_domain ~ WS? ~ property_domain

View file

@ -175,7 +175,7 @@ pub fn parse_inner(pairs: Pair<Rule>) -> Result<ASTUnit> {
} }
*/ */
pub fn to_docstring(pair: Pair<Rule>, file: &Arc<FileMap>) -> SpannedUnit { pub fn to_docstring(pair: Pair<'_, Rule>, file: &Arc<FileMap>) -> SpannedUnit {
let pair = pair.into_inner().next().unwrap(); let pair = pair.into_inner().next().unwrap();
match pair.as_rule() { match pair.as_rule() {
@ -238,7 +238,7 @@ pub fn to_parameters(mut pairs: Pairs<Rule>) -> Vec<Parameter> {
} }
*/ */
pub fn to_value_other(pair: Pair<Rule>) -> Option<String> { pub fn to_value_other(pair: Pair<'_, Rule>) -> Option<String> {
let inner = pair.into_inner().next().unwrap(); let inner = pair.into_inner().next().unwrap();
match inner.as_rule() { match inner.as_rule() {
@ -252,7 +252,7 @@ pub fn to_value_other(pair: Pair<Rule>) -> Option<String> {
} }
#[allow(unused)] #[allow(unused)]
pub fn to_field(pair: Pair<Rule>, file: &Arc<FileMap>) -> ASTUnit { pub fn to_field(pair: Pair<'_, Rule>, file: &Arc<FileMap>) -> ASTUnit {
let pairs = pair.into_inner(); let pairs = pair.into_inner();
let mut docstring = vec![]; let mut docstring = vec![];
@ -298,7 +298,7 @@ pub fn to_property(pair: Pair<Rule>, file: &Arc<FileMap>) -> ASTUnit {
*/ */
#[allow(unused)] #[allow(unused)]
fn to_function(pair: Pair<Rule>) -> ASTUnit { fn to_function(pair: Pair<'_, Rule>) -> ASTUnit {
let inner = pair.into_inner(); let inner = pair.into_inner();
let mut synchronous = true; let mut synchronous = true;
@ -370,7 +370,7 @@ fn to_argument(pairs: Pairs<Rule>) -> Argument {
} }
*/ */
pub fn to_expression_block(pair: Pair<Rule>) -> ASTUnit { pub fn to_expression_block(pair: Pair<'_, Rule>) -> ASTUnit {
let inner = pair.into_inner().next().unwrap(); let inner = pair.into_inner().next().unwrap();
// let mut expression = vec![]; // let mut expression = vec![];

View file

@ -18,6 +18,7 @@ use pest::Parser;
pub struct SchemaParser; pub struct SchemaParser;
#[allow(unused)]
pub fn from_path(path: &Path) -> Result<SourcedWholeRc> { pub fn from_path(path: &Path) -> Result<SourcedWholeRc> {
if !path.exists() { bail!("Path doesn't exist: {:?}", path) } if !path.exists() { bail!("Path doesn't exist: {:?}", path) }
let source = std::fs::read_to_string(path).unwrap(); let source = std::fs::read_to_string(path).unwrap();
@ -47,7 +48,7 @@ pub fn parse_source(source: String, name: String) -> Result<SourcedWholeRc> {
} }
#[allow(unused)] #[allow(unused)]
pub fn parse_inner(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> { pub fn parse_inner(pair: Pair<'_, Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> {
match pair.as_rule() { match pair.as_rule() {
Rule::namespace => { Rule::namespace => {
let span = pair.as_span(); let span = pair.as_span();
@ -261,7 +262,7 @@ pub fn parse_inner(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit>
} }
pub fn to_docstring(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> { pub fn to_docstring(pair: Pair<'_, Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> {
let pair = pair.into_inner().next().unwrap(); let pair = pair.into_inner().next().unwrap();
match pair.as_rule() { match pair.as_rule() {
@ -299,7 +300,7 @@ pub fn to_docstring(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit
#[allow(unused)] #[allow(unused)]
pub fn to_parameter(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> { pub fn to_parameter(pair: Pair<'_, Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> {
let pair_span = pair.as_span(); let pair_span = pair.as_span();
let unit_span = file.insert_span(pair_span.start(), pair_span.end()); let unit_span = file.insert_span(pair_span.start(), pair_span.end());
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
@ -323,7 +324,7 @@ pub fn to_parameter(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit
#[allow(unused)] #[allow(unused)]
pub fn to_field(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> { pub fn to_field(pair: Pair<'_, Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> {
let pair_span = pair.as_span(); let pair_span = pair.as_span();
let unit_span = file.insert_span(pair_span.start(), pair_span.end()); let unit_span = file.insert_span(pair_span.start(), pair_span.end());
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
@ -354,7 +355,7 @@ pub fn to_field(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> {
})) }))
} }
pub fn to_property(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> { pub fn to_property(pair: Pair<'_, Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> {
let pair_span = pair.as_span(); let pair_span = pair.as_span();
let unit_span = file.insert_span(pair_span.start(), pair_span.end()); let unit_span = file.insert_span(pair_span.start(), pair_span.end());
let inner = pair.into_inner().next().unwrap(); let inner = pair.into_inner().next().unwrap();
@ -380,7 +381,7 @@ pub fn to_property(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit>
#[allow(unused)] #[allow(unused)]
fn to_enum_variant(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> { fn to_enum_variant(pair: Pair<'_, Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> {
let pair_span = pair.as_span(); let pair_span = pair.as_span();
let unit_span = file.insert_span(pair_span.start(), pair_span.end()); let unit_span = file.insert_span(pair_span.start(), pair_span.end());
let inner = pair.into_inner(); let inner = pair.into_inner();
@ -405,7 +406,7 @@ fn to_enum_variant(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit>
} }
#[allow(unused)] #[allow(unused)]
fn to_function(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> { fn to_function(pair: Pair<'_, Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> {
let pair_span = pair.as_span(); let pair_span = pair.as_span();
let unit_span = file.insert_span(pair_span.start(), pair_span.end()); let unit_span = file.insert_span(pair_span.start(), pair_span.end());
let inner = pair.into_inner(); let inner = pair.into_inner();
@ -436,10 +437,10 @@ fn to_function(pair: Pair<Rule>, file: &Arc<FileMap>) -> Result<SpannedUnit> {
let kind_span = kind_pair.as_span(); let kind_span = kind_pair.as_span();
arguments.push((unit_span, ASTUnit::Argument { arguments.push((unit_span, ASTUnit::Argument {
name: Some(( name: (
file.insert_span(name_span.start(), name_span.end()), file.insert_span(name_span.start(), name_span.end()),
name_pair.as_str().to_owned() name_pair.as_str().to_owned()
)), ),
kind: ( kind: (
file.insert_span(kind_span.start(), kind_span.end()), file.insert_span(kind_span.start(), kind_span.end()),
kind_pair.as_str().to_owned() kind_pair.as_str().to_owned()

View file

@ -1,301 +0,0 @@
// Standard Uses
use std::cell::{RefCell, RefMut};
use std::rc::Rc;
// Local Uses
use crate::schema::idl::ast::unit::{ASTUnit, SpannedUnit};
use crate::schema::ir::context::SchemaContext;
use crate::schema::ir::compiler::interpreted::primitive::KindValue;
use crate::schema::ir::compiler::report::CompileError;
use crate::schema::ir::frozen::unit::FrozenUnit;
use crate::project::ir::context::ProjectContext;
use crate::report::ReportDetails;
// External Uses
#[allow(unused)]
pub fn interpret_context(
schema_context: &Rc<RefCell<SchemaContext>>, project_context: &RefMut<ProjectContext>
) -> Result<(), ReportDetails<CompileError>> {
let mut interpreted: Vec<FrozenUnit> = vec![];
let mut context = Some(schema_context.borrow());
for i in 0..context.as_ref().unwrap().schema.1.len() {
let spanned_unit = &context.unwrap().schema.1[i];
use crate::schema::idl::ast::unit::ASTUnit::*;
match &spanned_unit.1 {
Namespace(s, n) => {
let name = n.clone();
let Some(ctx)
= project_context.find_schema_by_import(&n) else
{
return Err(ReportDetails {
// kind: "Namespace".to_string(),
/*
message: format!(
"Namespace {} used in another schema: {} and {},\n \
only one schema per namespace is allowed",
n, context.main.0.filename(), unit_namespace.unwrap().0.filename()
),
start: 0, end: 0,
*/
phantom: Default::default(),
span: None,
})
};
context = None;
let mut ctx_mut = schema_context.borrow_mut();
if let Some(name) = &ctx_mut.compile_state.namespace {
panic!("Namespace {} was already previously set", name)
} else {
ctx_mut.compile_state.namespace = Some(name)
}
}
Docstring {..} => {
todo!()
}
Import(s, i) => {
/*
let Some(ctx)
= project_context.find_schema_by_import(i) else {
panic!("No import")
};
*/
}
// Docstring { .. } => {}
Constant {
docstring, name,
kind, default_value
} => {
/*
let kind_value = primitive::to_kind_value(
schema_context, kind, default_value
);
*/
}
Property { .. } => {}
Parameter { .. } => {}
ExpressionBlock { .. } => {}
Enum { .. } => {}
EnumVariant { .. } => {}
Settings { .. } => {}
Struct { .. } => {}
Protocol { .. } => {}
Function { .. } => {}
Argument { .. } => {}
Error { .. } => {}
Validator { .. } => {}
Field { .. } => {}
}
context = Some(schema_context.borrow());
}
// Ok(context.unwrap().compile_state.to_frozen())
Ok(())
/*
for (unit, span) in &context.config.1 {
use crate::schema::idl::ast::unit::ASTUnit::*;
match unit {
ASTUnit::Namespace(n) => {
let unit_namespace = context.find_whole_unit_by_import(n);
/*
if unit_namespace.is_some() {
return Err(ReportDetails {
kind: "Namespace".to_string(),
message: format!(
"Namespace {} used in another schema: {} and {},\n \
only one schema per namespace is allowed",
n, context.main.0.filename(), unit_namespace.unwrap().0.filename()
),
start: 0, end: 0,
})
}
*/
interpreted.push(FrozenUnit::Namespace(n.clone()));
},
Import(_) => {
let import = interpret_node(&context, unit)?;
interpreted.push(import);
}
Constant { .. } => {
let constant = interpret_node(&context, unit)?;
interpreted.push(constant);
}
Enum { .. } => {
let r#enum = interpret_node(&context, unit)?;
interpreted.push(r#enum);
}
/*
Unit::Settings { .. } => {}
Unit::Struct { .. } => {}
Unit::Protocol { .. } => {}
Unit::Error { .. } => {}
*/
Validator { .. } => {
let validator = interpret_node(&context, unit)?;
interpreted.push(validator);
}
/*
//r => panic!("Left to impl: {:?}", r)
*/
_ => {}
}
}
*/
}
#[allow(unused)]
pub fn interpret_node(context: &SchemaContext, node: &ASTUnit)
-> Result<FrozenUnit, ReportDetails<CompileError>>
{
let schema_ctx = context.project_context.clone().unwrap();
let project_ctx = context.project_context.clone().unwrap();
use crate::schema::idl::ast::unit::ASTUnit::*;
match node {
Namespace(_, n) => {
let mut found: Option<&SchemaContext> = None;
/*
for relative_ctx in schema_ctx.borrow().schema_contexts.iter() {
if unit::namespace(&relative_ctx.schema.1) == n {
/*
if found.is_some() {
return Err(ReportDetails {
kind: "namespace".to_string(),
message: format!(
"Found namespace {} when its already declared in {}",
&n, &relative_ctx.main.0.filename()
),
start: 0, end: 0,
})
}
*/
found = Some(relative_ctx)
}
}
*/
}
Import(_, i) => {
let relative_unit = project_ctx.borrow().find_schema_by_import(&i);
/*
if relative_unit.is_none() {
let relative_unit = relative_unit.unwrap();
return Err(ReportDetails {
kind: "import".to_string(),
message: format!("Could not find namespace of {}", relative_unit.0.filename()),
start: 0, end: 0,
})
}
*/
return Ok(FrozenUnit::Import(i.clone()))
},
Constant {
name: (_, name), kind: (_, kind),
default_value, ..
} => {
/*
let kind_value = primitive::to_kind_value(kind, default_value);
return Ok(FrozenUnit::Constant {
docstring: None,
name: name.clone(), kind_value
})
*/
}
Enum { name, variants, .. } => {
let mut frozen_variants: Vec<FrozenUnit> = vec![];
for variant in variants {
pub(crate) fn to_variant(variant: &ASTUnit) -> KindValue {
match variant {
EnumVariant { name, kind } => {
if kind.is_none() {
return KindValue::EnumVariant(
name.1.clone(),None
)
}
return KindValue::EnumVariant(
name.1.clone(), None
)
},
_ => panic!("Should not be here")
}
}
frozen_variants.push(FrozenUnit::EnumVariant(
to_variant(&variant.1)
));
}
return Ok(FrozenUnit::Enum {
docstring: None,
name: name.1.clone(),
variants: frozen_variants
})
}
/*
EnumVariant { .. } => {}
Settings { .. } => {}
Struct { .. } => {}
Protocol { .. } => {}
Function { .. } => {}
Error { .. } => {}
*/
#[allow(unused)]
Validator {
docstring, properties,
name, expression_block
} => {
let properties = to_properties(properties);
let expr_block = Box::new(FrozenUnit::ExpressionBlock { function_calls: vec![] });
return Ok(FrozenUnit::Validator {
docstring: Some("".to_owned()), // TODO: Docstrings should likely be a vector of units
properties: vec![],
name: name.1.clone(),
expression_block: expr_block
})
}
/*
Field { .. } => {}
Parameter { .. } => {}
Property { .. } => {}
ExpressionBlock { .. } => {}
*/
missing => unimplemented!("Missing implementation for node '{:?}'", missing)
}
panic!()
}
#[allow(unused)]
fn to_properties(nodes: &Vec<SpannedUnit>) -> Vec<FrozenUnit> {
let properties = vec![];
for node in nodes {
}
properties
}
pub fn into_frozen_unit() -> FrozenUnit {
todo!()
}

View file

@ -1,21 +1,28 @@
// Standard Uses // Standard Uses
use std::cell::Ref;
// Local Uses // Local Uses
use std::cell::RefCell;
use std::rc::Rc;
// External Uses
use strum_macros::EnumProperty;
use crate::schema::ir::context::SchemaContext; use crate::schema::ir::context::SchemaContext;
use crate::schema::ir::compiler::report::CompileError;
use crate::schema::ir::compiler::report;
use crate::project::ir::context::ProjectContext;
use crate::report::ReportDetails;
use crate::utils::codemap::Span; use crate::utils::codemap::Span;
// External Uses
use strum_macros::EnumProperty;
use snafu::ResultExt;
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[derive(EnumProperty)] #[derive(Debug, Eq, PartialEq)]
#[derive(Deserialize, Serialize, EnumProperty)]
#[repr(u8)] #[repr(u8)]
pub enum Primitive { pub enum Primitive {
#[strum(props(Name="bool", Description="boolean, 1 byte"))]
Boolean(Option<bool>) = 0,
#[strum(props(Name="u8", Description="unsigned 1 byte, 8 bits"))] #[strum(props(Name="u8", Description="unsigned 1 byte, 8 bits"))]
U8(Option<u8>) = 0, U8(Option<u8>),
#[strum(props(Name="u16", Description="unsigned 2 bytes, 16 bits"))] #[strum(props(Name="u16", Description="unsigned 2 bytes, 16 bits"))]
U16(Option<u16>), U16(Option<u16>),
@ -53,6 +60,9 @@ pub enum Primitive {
impl Primitive { impl Primitive {
pub fn value_str(&self) -> Option<String> { pub fn value_str(&self) -> Option<String> {
match self { match self {
Primitive::Boolean(b) => {
if let Some(b) = b { Some(b.to_string()) } else { None }
}
Primitive::U8(u) => { Primitive::U8(u) => {
if let Some(u) = u { Some(u.to_string()) } else { None } if let Some(u) = u { Some(u.to_string()) } else { None }
} }
@ -92,6 +102,11 @@ impl Primitive {
} }
} }
pub fn name(&self) -> &str {
use strum::EnumProperty;
self.get_str("Name").unwrap()
}
pub fn name_description(&self) -> String { pub fn name_description(&self) -> String {
use strum::EnumProperty; use strum::EnumProperty;
format!("{}({})", self.get_str("Name").unwrap(), self.get_str("Description").unwrap()) format!("{}({})", self.get_str("Name").unwrap(), self.get_str("Description").unwrap())
@ -113,14 +128,14 @@ pub enum KindValue {
Primitive(Primitive), Primitive(Primitive),
EnumVariant(String, Option<Box<KindValue>>), EnumVariant(String, Option<Box<KindValue>>),
Union(Vec<KindValue>), Union(Vec<KindValue>),
Namespaced(String) Namespaced(String, Option<Box<KindValue>>)
} }
impl KindValue { impl KindValue {
pub fn name_and_value(&self) -> (String, String) { pub fn name_and_value(&self) -> (String, Option<String>) {
match self { match self {
KindValue::Primitive(primitive) => { KindValue::Primitive(primitive) => {
return (primitive.name_description(), primitive.value_str().unwrap()) return (primitive.name().to_owned(), Some(primitive.value_str().unwrap()))
} }
KindValue::EnumVariant(name, value) => { KindValue::EnumVariant(name, value) => {
let value = value.as_ref().unwrap(); let value = value.as_ref().unwrap();
@ -131,36 +146,121 @@ impl KindValue {
todo!() todo!()
} }
#[allow(unused)] #[allow(unused)]
KindValue::Namespaced(namespace) => { KindValue::Namespaced(namespace, ..) => {
todo!() todo!()
} }
} }
} }
} }
pub fn resolve_kind_value(
pub(crate) fn to_kind_value( schema_context: &Ref<'_, SchemaContext<'_>>, project_context: &'_ ProjectContext<'_>,
schema_context: &Rc<RefCell<SchemaContext>>,
kind: &(Span, String), value: &Option<(Span, String)> kind: &(Span, String), value: &Option<(Span, String)>
) -> KindValue { ) -> Result<KindValue, Box<dyn snafu::Error>> {
if value.is_none() { if value.is_none() {
return to_kind_only(kind) if let Some(kind) = to_kind_only(schema_context, project_context, kind) {
} return Ok(kind)
KindValue::Primitive(
to_primitive(schema_context, kind, value.clone().unwrap().1).unwrap()
)
}
fn to_kind_only(kind: &(Span, String)) -> KindValue {
match kind {
&_ => panic!("Cant")
} }
} }
fn to_primitive( if let Some(kind_value) = to_kind_value(
schema_context: &Rc<RefCell<SchemaContext>>, schema_context, kind, &value.as_ref().unwrap()
kind: &(Span, String), value: String ) {
return Ok(kind_value)
};
Err(CompileError::TypeNotFound { name: kind.1.clone() })
.context(report::CompileSnafu {
details: ReportDetails::fetch(schema_context, &kind.0).unwrap()
})?
}
#[allow(unused)]
pub(crate) fn to_kind_value(
schema_context: &Ref<'_, SchemaContext<'_>>,
kind: &(Span, String), value: &(Span, String)
) -> Option<KindValue> {
if let Some(primitive) = to_primitive_kind_value(kind, &value.1) {
return Some(KindValue::Primitive(primitive))
}
None
}
#[allow(unused)]
pub(crate) fn to_kind_only(
schema_context: &Ref<'_, SchemaContext<'_>>, project_context: &'_ ProjectContext<'_>,
kind: &(Span, String)
) -> Option<KindValue> {
if let Some(primitive) = to_primitive_kind_only(kind) {
return Some(KindValue::Primitive(primitive))
}
if let Some(namespaced) = to_namespaced_kind_only(schema_context, kind) {
return Some(namespaced)
}
if let Some(union) = to_union_kind_only(schema_context, kind) {
return Some(union)
}
None
}
fn to_namespaced_kind_only(
schema_context: &Ref<'_, SchemaContext<'_>>, kind: &(Span, String)
) -> Option<KindValue> {
let state = schema_context.compile_state.borrow();
for (_, structure) in state.structures.iter() {
if structure.name.1 == kind.1 {
return Some(KindValue::Namespaced(
structure.name.1.clone(), None
))
}
}
for (_, constant) in state.consts.iter() {
if constant.name.1 == kind.1 {
return Some(KindValue::Namespaced(
constant.name.1.clone(), None
))
}
}
None
}
fn to_union_kind_only(
schema_context: &Ref<'_, SchemaContext<'_>>, kind: &(Span, String)
) -> Option<KindValue> {
todo!()
}
fn to_primitive_kind_only(kind: &(Span, String)) -> Option<Primitive> {
use self::Primitive::*;
match &*kind.1 {
"u8" => Some(U8(None)),
"u16" => Some(U16(None)),
"u32" => Some(U32(None)),
"u64" => Some(U64(None)),
"u128" => Some(U128(None)),
"s8" => Some(S8(None)),
"s16" => Some(S16(None)),
"s32" => Some(S32(None)),
"s64" => Some(S64(None)),
"s128" => Some(S128(None)),
"str" => Some(String(None)),
"bool" => Some(Boolean(None)),
_ => { None }
}
}
fn to_primitive_kind_value<'a>(
kind: &(Span, String), value: &str
) -> Option<Primitive> { ) -> Option<Primitive> {
use self::Primitive::*; use self::Primitive::*;
let kv = match &*kind.1 { let kv = match &*kind.1 {
@ -177,6 +277,7 @@ fn to_primitive(
"s128" => S128(Some(value.parse().unwrap())), "s128" => S128(Some(value.parse().unwrap())),
"str" => String(Some(value.to_owned())), "str" => String(Some(value.to_owned())),
"bool" => Boolean(Some(value.parse().unwrap())),
_ => { panic!("Got unknown type '{:#}'", kind.1) } _ => { panic!("Got unknown type '{:#}'", kind.1) }
}; };

View file

@ -1,6 +1,5 @@
// Relative Modules // Relative Modules
pub mod sanitizer; pub mod sanitizer;
pub mod serialization; pub mod serialization;
pub mod primitive; pub mod kind_search;
pub mod interpreter;

View file

@ -7,6 +7,6 @@ use crate::schema::ir::context::SchemaContext;
#[allow(unused)] #[allow(unused)]
fn sanitize_context_units(context: &SchemaContext) { fn sanitize_context_units(context: &SchemaContext<'_>) {
todo!() todo!()
} }

View file

@ -1,82 +1,77 @@
// Standard Uses // Standard Uses
use std::cell::{RefCell, RefMut}; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use snafu::ResultExt;
// Crate Uses // Crate Uses
use crate::report::ReportDetails; use crate::report::ReportDetails;
use crate::schema::ir::compiler::report::CompileError;
use crate::schema::ir::context::SchemaContext; use crate::schema::ir::context::SchemaContext;
use crate::project::ir::context::ProjectContext; use crate::project::ir::context::ProjectContext;
use crate::schema::ir::compiler::interpreter::semi_frozen::SemiFrozenUnit; use crate::schema::ir::compiler::interpreter::semi_frozen;
use crate::schema::ir::compiler::report;
use crate::schema::ir::compiler::report::CompileError;
// External Uses // External Uses
pub fn compile_schema_metadata( pub fn compile_schema_metadata<'a>(
schema_context: &Rc<RefCell<SchemaContext>>, project_context: &RefMut<ProjectContext> schema_context: Rc<RefCell<SchemaContext<'a>>>,
) -> Result<(), ReportDetails<CompileError>> { project_context: &ProjectContext<'a>
let mut context = Some(RefCell::borrow(&schema_context)); ) -> Result<(), Box<dyn snafu::Error>> {
let schema_ctx = schema_context.borrow();
for i in 0..context.as_ref().unwrap().schema.1.len() { for i in 0..schema_ctx.schema.1.len() {
let spanned_unit = &context.as_ref().unwrap().schema.1[i]; let spanned_unit = &schema_ctx.schema.1[i];
use crate::schema::idl::ast::unit::ASTUnit::*; use crate::schema::idl::ast::unit::ASTUnit::*;
match &spanned_unit.1 { match &spanned_unit.1 {
Namespace(_, n) => { Namespace(span, n) => {
let name = n.clone(); let name = n.clone();
let Some(_) let Some(_) = project_context.find_schema_by_import(&n) else {
= project_context.find_schema_by_import(&n) else Err(CompileError::NamespaceCollision {
{ origin: "aa".to_string(), target: "aaa".to_string()
return Err(ReportDetails { }).context(report::CompileSnafu {
// kind: "Namespace".to_string(), details: ReportDetails::fetch(&schema_ctx, span).unwrap()
/* })?
message: format!(
"Namespace {} used in another schema: {} and {},\n \
only one schema per namespace is allowed",
n, context.main.0.filename(), unit_namespace.unwrap().0.filename()
),
start: 0, end: 0,
*/
phantom: Default::default(),
span: None,
})
}; };
context = None; let mut compile_state = schema_ctx.compile_state.borrow_mut();
let mut ctx_mut = schema_context.borrow_mut(); if let Some(name) = &compile_state.namespace {
if let Some(name) = &ctx_mut.compile_state.namespace {
panic!("Namespace {} was already previously set", name) panic!("Namespace {} was already previously set", name)
} else { } else {
ctx_mut.compile_state.namespace = Some(name) compile_state.namespace = Some(name)
} }
drop(ctx_mut);
} }
Docstring {..} => { Docstring {..} => {
todo!() todo!()
} }
Import(_, _) => { Import(span, import) => {
/* let spanned = Rc::clone(&spanned_unit);
let Some(ctx)
= project_context.find_schema_by_import(i) else { schema_ctx.compile_state.borrow_mut().imports.entry(spanned).or_insert(
panic!("No import") semi_frozen::Import {
}; namespace: (*span, import.clone()),
*/ // alias: alias.clone
}
);
} }
// Docstring { .. } => {} // Docstring { .. } => {}
#[allow(unused)]
Constant { name, ..} => { Constant { name, ..} => {
let name = name.clone(); let spanned_unit = Rc::clone(&spanned_unit);
context = None; schema_ctx.compile_state.borrow_mut().consts
.entry(spanned_unit).or_insert(
let mut ctx_mut = schema_context.borrow_mut(); semi_frozen::Constant { name: name.clone() }
let spanned_unit = &schema_context.borrow().schema.1[i];
let su = Rc::clone(&spanned_unit);
ctx_mut.compile_state.consts.entry(su).or_insert(
SemiFrozenUnit::Constant { name: name.clone() }
); );
}
Struct { name, .. } => {
let spanned_unit = Rc::clone(&spanned_unit);
context = Some(RefCell::borrow(&schema_context)); schema_ctx.compile_state.borrow_mut().structures
.entry(spanned_unit).or_insert(
semi_frozen::Structure { name: name.clone() }
);
} }
Property { .. } => {} Property { .. } => {}
Parameter { .. } => {} Parameter { .. } => {}
@ -84,16 +79,20 @@ pub fn compile_schema_metadata(
Enum { .. } => {} Enum { .. } => {}
EnumVariant { .. } => {} EnumVariant { .. } => {}
Settings { .. } => {} Settings { .. } => {}
Struct { .. } => {} Protocol { name, .. } => {
Protocol { .. } => {} let spanned_unit = Rc::clone(&spanned_unit);
schema_ctx.compile_state.borrow_mut().protocols
.entry(spanned_unit).or_insert(
semi_frozen::Protocol { name: name.clone() }
);
}
Function { .. } => {} Function { .. } => {}
Argument { .. } => {} Argument { .. } => {}
Error { .. } => {} Error { .. } => {}
Validator { .. } => {} Validator { .. } => {}
Field { .. } => {} Field { .. } => {}
} }
context = Some(RefCell::borrow(&schema_context));
} }
Ok(()) Ok(())

View file

@ -1,17 +1,343 @@
// Standard Uses // Standard Uses
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell; use std::cell::{Ref, RefCell};
// Crate Uses // Crate Uses
use crate::report::ReportDetails;
use crate::schema::ir::compiler::report::CompileError;
use crate::schema::ir::context::SchemaContext; use crate::schema::ir::context::SchemaContext;
use crate::schema::idl::ast::unit::{ASTUnit, SpannedUnit};
use crate::schema::ir::compiler::interpreted::kind_search;
use crate::schema::ir::compiler::interpreted::kind_search::{KindValue};
use crate::schema::ir::frozen::unit::{FrozenArgument, FrozenUnit};
use crate::project::ir::context::ProjectContext;
// External Uses // External Uses
pub fn compile_schema_metadata(schema_context: &Rc<RefCell<SchemaContext>> #[allow(unused)]
) -> Result<(), ReportDetails<CompileError>> pub fn compile_schema<'a>(
{ schema_context: Rc<RefCell<SchemaContext<'a>>>,
project_context: &ProjectContext<'a>
) -> Result<(), Box<dyn snafu::Error>> {
let schema_ctx = schema_context.borrow();
let mut interpreted: Vec<FrozenUnit> = vec![];
for spanned_unit in &schema_ctx.schema.1 {
use crate::schema::idl::ast::unit::ASTUnit::*;
match &spanned_unit.1 {
Namespace(..) => {}
Docstring {..} => {
todo!()
}
Import(s, i) => {
let Some(import_ctx)
= project_context.find_schema_by_import(i) else {
panic!("No schema found by import '{}'", i)
};
}
// Docstring { .. } => {}
Constant {
docstring, name,
kind, default_value
} => {
let state = schema_ctx.compile_state.borrow();
let kind_value = kind_search::resolve_kind_value(
&schema_ctx, project_context, kind, default_value
)?;
interpreted.push(FrozenUnit::Constant {
docstring: None,
name: name.1.clone(),
kind_value,
});
}
Property { .. } => {}
Parameter { .. } => {}
ExpressionBlock { .. } => {}
Enum { .. } => {}
EnumVariant { .. } => {}
Settings { .. } => {}
Struct { .. } => {}
Protocol {
docstring, parameters,
name, functions
} => {
let state = schema_ctx.compile_state.borrow();
let mut params = vec![];
let mut funcs = vec![];
for function in functions {
funcs.push(to_function_frozen(
&schema_ctx, &project_context, function
)?);
}
interpreted.push(FrozenUnit::Protocol {
docstring: "".to_string(),
parameters: params,
name: name.1.clone(),
functions: funcs,
});
}
Function { name, .. } => {
}
Argument { .. } => {}
Error { .. } => {}
Validator { .. } => {}
Field { .. } => {}
}
}
drop(schema_ctx);
let mut schema_ctx = RefCell::borrow_mut(&schema_context);
schema_ctx.frozen_schema = Some(interpreted);
Ok(())
/*
for (unit, span) in &context.config.1 {
use crate::schema::idl::ast::unit::ASTUnit::*;
match unit {
ASTUnit::Namespace(n) => {
let unit_namespace = context.find_whole_unit_by_import(n);
/*
if unit_namespace.is_some() {
return Err(ReportDetails {
kind: "Namespace".to_string(),
message: format!(
"Namespace {} used in another schema: {} and {},\n \
only one schema per namespace is allowed",
n, context.main.0.filename(), unit_namespace.unwrap().0.filename()
),
start: 0, end: 0,
})
}
*/
interpreted.push(FrozenUnit::Namespace(n.clone()));
},
Import(_) => {
let import = interpret_node(&context, unit)?;
interpreted.push(import);
}
Constant { .. } => {
let constant = interpret_node(&context, unit)?;
interpreted.push(constant);
}
Enum { .. } => {
let r#enum = interpret_node(&context, unit)?;
interpreted.push(r#enum);
}
/*
Unit::Settings { .. } => {}
Unit::Struct { .. } => {}
Unit::Protocol { .. } => {}
Unit::Error { .. } => {}
*/
Validator { .. } => {
let validator = interpret_node(&context, unit)?;
interpreted.push(validator);
}
/*
//r => panic!("Left to impl: {:?}", r)
*/
_ => {}
}
}
*/
}
fn to_function_frozen(
schema_ctx: &Ref<'_, SchemaContext<'_>>, project_context: &'_ ProjectContext<'_>,
spanned_unit: &SpannedUnit
) -> Result<FrozenUnit, Box<dyn snafu::Error>> {
#[allow(unused)]
let ASTUnit::Function {
docstring, parameters, name,
asynchronous,
arguments, returns, throws
} = &spanned_unit.1 else { panic!() };
let sync = || { if let Some(_) = asynchronous { false } else { true } };
let mut args = vec![];
let mut rets = vec![];
for (_, unit) in arguments {
let ASTUnit::Argument { name, kind } = unit else { panic!() };
let Some(kind) = kind_search::to_kind_only(
&schema_ctx, project_context, kind
) else { panic!() };
args.push(FrozenArgument {
name: name.1.clone(),
kind
});
}
for ret in returns {
let Some(kind) = kind_search::to_kind_only(
&schema_ctx, project_context, ret
) else { panic!() };
rets.push(kind);
}
Ok(FrozenUnit::Function {
docstring: "".to_string(),
name: name.1.clone(),
synchronous: sync(),
// direction: Box::new(()),
arguments: args,
returns: rets,
throws: vec![],
})
}
#[allow(unused)]
pub fn interpret_node<'a>(
schema_context: &'a SchemaContext<'a>,
project_context: &'a ProjectContext<'a>,
node: &ASTUnit
) -> Result<FrozenUnit, Box<dyn snafu::Error>>
{
use crate::schema::idl::ast::unit::ASTUnit::*;
match node {
Namespace(_, n) => {
let mut found: Option<&SchemaContext<'a>> = None;
/*
for relative_ctx in schema_ctx.borrow().schema_contexts.iter() {
if unit::namespace(&relative_ctx.schema.1) == n {
/*
if found.is_some() {
return Err(ReportDetails {
kind: "namespace".to_string(),
message: format!(
"Found namespace {} when its already declared in {}",
&n, &relative_ctx.main.0.filename()
),
start: 0, end: 0,
})
}
*/
found = Some(relative_ctx)
}
}
*/
}
Import(_, i) => {
let relative_unit = project_context.find_schema_by_import(&i);
/*
if relative_unit.is_none() {
let relative_unit = relative_unit.unwrap();
return Err(ReportDetails {
kind: "import".to_string(),
message: format!("Could not find namespace of {}", relative_unit.0.filename()),
start: 0, end: 0,
})
}
*/
return Ok(FrozenUnit::Import(i.clone()))
},
Constant {
name: (_, name), kind: (_, kind),
default_value, ..
} => {
/*
let kind_value = primitive::to_kind_value(kind, default_value);
return Ok(FrozenUnit::Constant {
docstring: None,
name: name.clone(), kind_value
})
*/
}
Enum { name, variants, .. } => {
let mut frozen_variants: Vec<FrozenUnit> = vec![];
for variant in variants {
pub(crate) fn to_variant(variant: &ASTUnit) -> KindValue {
match variant {
EnumVariant { name, kind } => {
if kind.is_none() {
return KindValue::EnumVariant(
name.1.clone(),None
)
}
return KindValue::EnumVariant(
name.1.clone(), None
)
},
_ => panic!("Should not be here")
}
}
frozen_variants.push(FrozenUnit::EnumVariant(
to_variant(&variant.1)
));
}
return Ok(FrozenUnit::Enum {
docstring: None,
name: name.1.clone(),
variants: frozen_variants
})
}
/*
EnumVariant { .. } => {}
Settings { .. } => {}
Struct { .. } => {}
Protocol { .. } => {}
Function { .. } => {}
Error { .. } => {}
*/
#[allow(unused)]
Validator {
docstring, properties,
name, expression_block
} => {
let properties = to_properties(properties);
let expr_block = Box::new(FrozenUnit::ExpressionBlock { function_calls: vec![] });
return Ok(FrozenUnit::Validator {
docstring: Some("".to_owned()), // TODO: Docstrings should likely be a vector of units
properties: vec![],
name: name.1.clone(),
expression_block: expr_block
})
}
/*
Field { .. } => {}
Parameter { .. } => {}
Property { .. } => {}
ExpressionBlock { .. } => {}
*/
missing => unimplemented!("Missing implementation for node '{:?}'", missing)
}
panic!()
}
#[allow(unused)]
fn to_properties(nodes: &Vec<SpannedUnit>) -> Vec<FrozenUnit> {
let properties = vec![];
for node in nodes {
}
properties
}
pub fn into_frozen_unit() -> FrozenUnit {
todo!() todo!()
} }

View file

@ -6,9 +6,28 @@ use crate::utils::codemap::Span;
// External Uses // External Uses
pub enum SemiFrozenUnit {
Constant { #[derive(Clone)]
name: (Span, String) pub struct Import {
}, pub(crate) namespace: (Span, String),
// TODO: Alias of imports for schemas, objects, etc, is needed for namespace conflicts
// pub(crate) alias: (Span, String)
}
// TODO: All of these structures might be able to be replace with a single one, since
// a lot of them might just need to have a name and span to the objects
#[derive(Clone)]
pub struct Structure {
pub(crate) name: (Span, String)
}
#[derive(Clone)]
pub struct Constant {
pub(crate) name: (Span, String)
}
#[derive(Clone)]
pub struct Protocol {
pub(crate) name: (Span, String)
} }

View file

@ -1,47 +1,63 @@
// Standard Uses // Standard Uses
use std::fmt::{Display, Formatter};
// Crate Uses // Crate Uses
use crate::report::ReportDetails; use crate::report::ReportDetails;
// External Uses // External Uses
use snafu::Snafu; use snafu::Snafu;
use strum::EnumProperty;
use strum_macros::FromRepr;
// TODO: repr(u16) is here so we could turn a enum variant instance into its corresponding number
// however i didn't find how to do it without having to match pattern every each one of
// the variants and return the number by casting the variant, so strum props were used.
// If in the future we know of a better solution, it should be applied
#[repr(u16)] #[repr(u16)]
#[derive(EnumProperty)]
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
pub enum CompileError { pub enum CompileError {
#[strum(props(Id="1"))] #[snafu(display(
#[snafu(display("Found namespace '{target}' when its already declared in '{origin}'"))] "Found namespace '{target}' when its already declared in '{origin}'"
Namespace { source: std::io::Error, origin: String, target: String } = 1, ))]
NamespaceCollision { origin: String, target: String } = 0,
#[snafu(display("No type found by name '{name}'"))]
TypeNotFound { name: String },
} }
impl CompileError { impl CompileError {
pub fn code(&self) -> u16 { pub(crate) fn code(&self) -> u16 {
self.get_str("Id").expect("Variant does not have a 'Id' property").parse().unwrap() unsafe { *<*const _>::from(self).cast::<u16>() }
}
}
impl Display for ReportDetails<CompileError> {
#[allow(unused)]
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "TODO: Display needs implementation here")
} }
} }
// TODO: Same case as the enum `CompileError` about the repr #[repr(u16)]
#[derive(EnumProperty, FromRepr)]
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
pub enum CompileWarning { pub enum CompileWarning {
#[strum(props(Id="1"))]
#[snafu(display("No dependencies were assigned, this will automatically add Comline's langlib'"))] #[snafu(display("No dependencies were assigned, this will automatically add Comline's langlib'"))]
DependenciesNotFilled DependenciesNotFilled
} }
impl CompileWarning {
pub(crate) fn code(&self) -> u16 {
unsafe { *<*const _>::from(self).cast::<u16>() }
}
}
#[derive(Debug, Snafu)]
#[snafu(visibility(pub(crate)))]
pub enum Report {
#[snafu(display(
"Error[E0{}]: {source}\nAt line {}:{} (position {}:{})",
source.code(), details.line.start, details.line.end, details.pos.start, details.pos.end
))]
CompileErrorError {
source: CompileError,
details: ReportDetails,
},
#[snafu(display(
"Warning[W0{}]: {source}\nAt line {}:{} (position {}:{})",
source.code(), details.line.start, details.line.end, details.pos.start, details.pos.end
))]
CompileWarningError {
source: CompileWarning,
details: ReportDetails,
},
}

View file

@ -1,24 +1,28 @@
// Standard Uses
use std::rc::Rc;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::marker::PhantomData;
use std::rc::Rc;
// Local Uses // Local Uses
use crate::project::ir::context::ProjectContext;
use crate::schema::idl::ast::unit::{SourcedWholeRc, SpannedUnit}; use crate::schema::idl::ast::unit::{SourcedWholeRc, SpannedUnit};
use crate::schema::ir::compiler::interpreter::semi_frozen::SemiFrozenUnit; use crate::schema::ir::compiler::interpreter::semi_frozen;
use crate::schema::ir::frozen::unit::FrozenUnit; use crate::schema::ir::frozen::unit::FrozenUnit;
// External Uses // External Uses
#[derive(Default)] #[derive(Clone, Default)]
pub struct CompileState { pub struct CompileState<'e> {
pub namespace: Option<String>, pub namespace: Option<String>,
pub consts: HashMap<Rc<SpannedUnit>, SemiFrozenUnit> pub imports: HashMap<Rc<SpannedUnit>, semi_frozen::Import>,
pub consts: HashMap<Rc<SpannedUnit>, semi_frozen::Constant>,
pub structures: HashMap<Rc<SpannedUnit>, semi_frozen::Structure>,
pub protocols: HashMap<Rc<SpannedUnit>, semi_frozen::Protocol>,
pub phantom: PhantomData<&'e ()>,
} }
impl CompileState { #[allow(unused)]
impl<'e> CompileState<'_> {
pub(crate) fn to_frozen(&self) -> Vec<FrozenUnit> { pub(crate) fn to_frozen(&self) -> Vec<FrozenUnit> {
let mut interpreted = vec![]; let mut interpreted = vec![];
@ -28,40 +32,38 @@ impl CompileState {
} }
} }
pub struct SchemaContext { pub struct SchemaContext<'a> {
pub name: String,
pub schema: SourcedWholeRc, pub schema: SourcedWholeRc,
pub frozen_schema: Option<Vec<FrozenUnit>>, pub frozen_schema: Option<Vec<FrozenUnit>>,
pub project_context: Option<Rc<RefCell<ProjectContext>>>, // pub project_context: Option<&'a RefCell<ProjectContext<'a>>>,
pub compile_state: CompileState // pub project_context: Option<&'a mut ProjectContext<'a>>,
pub compile_state: RefCell<CompileState<'a>>
// pub compile_state: RefCell<CompileState>
} }
#[allow(unused)] #[allow(unused)]
impl SchemaContext { impl<'a> SchemaContext<'a> {
pub fn with_main(schema: SourcedWholeRc) -> Self{ pub fn with_main(schema: SourcedWholeRc, name: String) -> Self{
Self { Self {
name,
schema, schema,
frozen_schema: None, frozen_schema: None,
project_context: None, // project_context: None,
compile_state: Default::default(), compile_state: Default::default(),
} }
} }
pub fn with_project_and_main( pub fn with_project_and_main(
schema: SourcedWholeRc, project: Rc<RefCell<ProjectContext>> schema: SourcedWholeRc,
// project: &'a RefCell<ProjectContext<'a>>
name: String
) -> Self { ) -> Self {
Self { Self {
name,
schema, schema,
frozen_schema: None, frozen_schema: None,
project_context: Some(project), // project_context: Some(project),
compile_state: Default::default(),
}
}
pub fn with_main_no_std(schema: SourcedWholeRc) -> Self{
Self {
schema,
frozen_schema: None,
project_context: None,
compile_state: Default::default(), compile_state: Default::default(),
} }
} }

View file

@ -3,7 +3,7 @@ use std::fmt::Debug;
// Crate Uses // Crate Uses
use crate::schema::ir::frozen::unit::{FrozenUnit, FrozenWhole}; use crate::schema::ir::frozen::unit::{FrozenUnit, FrozenWhole};
use crate::schema::ir::compiler::interpreted::primitive::KindValue; use crate::schema::ir::compiler::interpreted::kind_search::KindValue;
// External Uses // External Uses
use downcast_rs::{Downcast, impl_downcast}; use downcast_rs::{Downcast, impl_downcast};
@ -18,8 +18,8 @@ pub trait Differ: Downcast + Debug {
&mut self, name: &str, left_kind_value: &KindValue, right_kind_value: &KindValue &mut self, name: &str, left_kind_value: &KindValue, right_kind_value: &KindValue
); );
fn differ( fn differ<'a>(
&self, previous: &Vec<FrozenUnit>, next: &FrozenWhole, &self, previous: &Vec<FrozenUnit>, next: &FrozenWhole<'a>,
document_gen: bool, auto_version: bool document_gen: bool, auto_version: bool
) { ) {
todo!() todo!()

View file

@ -2,14 +2,17 @@
// Crate Uses // Crate Uses
use crate::schema::ir::context::SchemaContext; use crate::schema::ir::context::SchemaContext;
use crate::schema::ir::compiler::interpreted::primitive::KindValue; use crate::schema::ir::compiler::interpreted::kind_search::KindValue;
// External Uses // External Uses
pub type FrozenWhole = (SchemaContext, Vec<FrozenUnit>); pub type FrozenWhole<'a> = (SchemaContext<'a>, Vec<FrozenUnit>);
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
// TODO: A lot of string instances could be &'a str, boxes could also get ditched, etc
#[derive(Deserialize, Serialize)]
#[derive(Debug, Eq, PartialEq)]
pub enum FrozenUnit { pub enum FrozenUnit {
// TODO: Are Tags really necessary anymore since we hash Frozen Units by blob, trees and commits? // TODO: Are Tags really necessary anymore since we hash Frozen Units by blob, trees and commits?
// Tag(String), // Tag(String),
@ -59,9 +62,9 @@ pub enum FrozenUnit {
docstring: String, docstring: String,
name: String, name: String,
synchronous: bool, synchronous: bool,
direction: Box<FrozenUnit>, // direction: Box<FrozenUnit>,
arguments: Vec<FrozenUnit>, arguments: Vec<FrozenArgument>,
returns: Vec<FrozenUnit>, returns: Vec<KindValue>,
throws: Vec<FrozenUnit> throws: Vec<FrozenUnit>
}, },
Error { Error {
@ -85,3 +88,10 @@ pub enum FrozenUnit {
kind_value: KindValue, kind_value: KindValue,
} }
} }
#[derive(Deserialize, Serialize)]
#[derive(Debug, Eq, PartialEq)]
pub struct FrozenArgument {
pub name: String,
pub kind: KindValue
}

View file

@ -6,7 +6,7 @@ use comline::schema::ir::frozen::unit::FrozenUnit;
// External Uses // External Uses
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use comline::autodoc; use comline::autodoc;
use comline::schema::ir::compiler::interpreted::primitive::{KindValue, Primitive}; use comline::schema::ir::compiler::interpreted::kind_search::{KindValue, Primitive};
static PREVIOUS_FROZEN_UNITS: Lazy<Vec<FrozenUnit>> = Lazy::new(|| static PREVIOUS_FROZEN_UNITS: Lazy<Vec<FrozenUnit>> = Lazy::new(||

View file

@ -5,8 +5,8 @@ use std::path::Path;
// External Uses // External Uses
use comline::schema::{idl, ir}; use comline::schema::{idl, ir};
use comline::schema::idl::constants::SCHEMA_EXTENSION;
use comline::schema::idl::ast::unit::ASTUnit; use comline::schema::idl::ast::unit::ASTUnit;
use comline::schema::idl::constants::SCHEMA_EXTENSION;
use comline::utils::codemap::Span; use comline::utils::codemap::Span;
@ -193,7 +193,9 @@ fn compile_unit() {
let path = Path::new(path); let path = Path::new(path);
let unit = idl::parser_new::from_path(path).unwrap(); let unit = idl::parser_new::from_path(path).unwrap();
let context = ir::context::SchemaContext::with_main(unit); let context = ir::context::SchemaContext::with_main(
unit, path.file_stem().unwrap().to_str().unwrap().to_owned()
);
/* /*
let frozen_unit = interpreter::interpret_context(context).unwrap(); let frozen_unit = interpreter::interpret_context(context).unwrap();

View file

@ -3,10 +3,12 @@ specification_version = 1
schema_paths = [ schema_paths = [
"ping.ids" "ping.ids"
"health.ids"
] ]
code_generation = { code_generation = {
languages = { languages = {
python#3.11.0 = { package_versions=[all] }
rust#1.70.0 = { package_versions=[all] } rust#1.70.0 = { package_versions=[all] }
} }
} }

View file

@ -0,0 +1,14 @@
# Generated code with Comline compiler and code generator
import typing
import ctypes
class HealthCheck(typing.Protocol):
def alive(self):
...
def capabilities(self):
...

View file

@ -0,0 +1,16 @@
# Generated code with Comline compiler and code generator
import typing
import ctypes
LOW_PING_RATE: typing.Final[ctypes.c_uint16] = 20
class Ping(typing.Protocol):
def ping(self):
...
def ping_limit(self):
...

View file

@ -0,0 +1,8 @@
// Generated code with Comline compiler and code generator
pub trait HealthCheck {
fn alive (&self);
fn capabilities (&self);
}

View file

@ -0,0 +1,10 @@
// Generated code with Comline compiler and code generator
pub const LOW_PING_RATE: u16 = 20;
pub trait Ping {
fn ping (&self);
fn ping_limit (&self);
}

View file

@ -2,12 +2,13 @@
namespace test::idl::health namespace test::idl::health
struct Capabilities { struct Capabilities {
names: str[] names: str
} }
/// Health check an address /// Health check an address
@provider=Any @provider=Any
protocol HealthCheck { protocol HealthCheck {
function alive() -> bool function alive() -> bool;
function capabilities() -> Capabilities;
} }

View file

@ -1,15 +1,17 @@
// Ping Schema // Ping Schema
namespace tests::idl::ping namespace test::idl::ping
const LOW_PING_RATE:u16 = 20; import test::idl::health
const LOW_PING_RATE: u16 = 20
/// Ping another address /// Ping another address
@provider=Any @provider=Any
protocol Ping { protocol Ping {
function ping() -> bool function ping() -> bool;
@timeout_ms=1000 @timeout_ms=1000
function ping_limit() -> bool function ping_limit() -> bool;
} }