Skip to content

Commit ef9ee25

Browse files
committed
WIP
1 parent f316b2d commit ef9ee25

File tree

14 files changed

+366
-133
lines changed

14 files changed

+366
-133
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rs/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ serde_yaml = "0.9"
4040
# both the schema and the input, so we need to depend on that as well, even
4141
# though we don't actually do any JSON serialization and deserialization.
4242
jsonschema = { version = "=0.15.0", default-features = false }
43-
serde_json = "1"
43+
serde_json = { version = "1", features = ["preserve_order"] }
4444

4545
# Used for checking identifier syntax (could be removed if regexes don't end up
4646
# being useful elsewhere too).

rs/src/output/diagnostic.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,9 @@ pub enum Classification {
246246
#[strum(props(HiddenDescription = "invalid compound vs. simple function name usage"))]
247247
LinkCompoundVsSimpleFunctionName = 3010,
248248

249+
#[strum(props(Description = "discouraged name"))]
250+
LinkDiscouragedName = 3011,
251+
249252
// Type-related diagnostics (group 4).
250253
#[strum(props(HiddenDescription = "type-related diagnostics"))]
251254
Type = 4000,

rs/src/output/extension/namespace.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,22 @@ impl<T> ResolutionResult<T> {
531531
self.expect(parse_context, if_not_applicable, |_, _| true, true, false)
532532
}
533533

534+
/// Emits an error if one or more definitions were found for this name
535+
/// resolution, to be used just before defining a new item.
536+
pub fn expect_not_yet_defined(&self, parse_context: &mut context::Context) {
537+
if !self.visible.is_empty() {
538+
traversal::push_diagnostic(
539+
parse_context,
540+
diagnostic::Level::Error,
541+
cause!(
542+
LinkDuplicateDefinition,
543+
"{} is already defined",
544+
self.unresolved_reference
545+
),
546+
);
547+
}
548+
}
549+
534550
/// Silently returns the first matching item, if any. If there are none,
535551
/// this just returns an unresolved reference. Use
536552
/// filter_items().expect_one() to formulate error messages if there are
@@ -567,18 +583,4 @@ impl<T> ResolutionResult<T> {
567583
.next()
568584
.flatten()
569585
}
570-
571-
/// Return an error if one or more definitions were found for this name
572-
/// resolution, to be used just before defining a new item.
573-
pub fn expect_not_yet_defined(&self) -> diagnostic::Result<()> {
574-
if self.visible.is_empty() {
575-
Ok(())
576-
} else {
577-
Err(cause!(
578-
LinkDuplicateDefinition,
579-
"{} is already defined",
580-
self.unresolved_reference
581-
))
582-
}
583-
}
584586
}

rs/src/output/extension/simple/type_class.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,27 @@ use crate::output::type_system::meta::pattern::Pattern;
1212
/// A definition of a user-defined type class.
1313
#[derive(Clone, Debug, PartialEq, Eq, Default)]
1414
pub struct Definition {
15-
/// The underlying structure of the type.
16-
pub structure: Vec<(String, data::class::Simple)>,
15+
/// Name of the type class.
16+
pub name: String,
1717

1818
/// The parameters expected by the data type.
1919
pub parameter_slots: Vec<ParameterSlot>,
2020

2121
/// Whether or not the last parameter slot is variadic.
2222
pub parameters_variadic: bool,
23+
24+
/// Optional underlying structure of the type.
25+
/// TODO: change to Option<Vec<(String, meta::Program)>> and propagate changes
26+
pub structure: Vec<(String, data::class::Simple)>,
2327
}
2428

2529
/// A parameter slot for a user-defined data type.
2630
#[derive(Clone, Debug, PartialEq, Eq)]
2731
pub struct ParameterSlot {
28-
/// YAML-provided name of the parameter.
32+
/// Name of the parameter.
2933
pub name: String,
3034

31-
/// YAML-provided human-readable description of the parameter.
35+
/// Human-readable description of the parameter.
3236
pub description: String,
3337

3438
/// Pattern for type- and bounds-checking parameters bound to this slot.

rs/src/parse/extensions/simple/builder.rs

Lines changed: 0 additions & 66 deletions
This file was deleted.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
//! Module providing private helper functions that are not specific to any
4+
//! particular simple extension construct.
5+
6+
use crate::output::diagnostic::Result;
7+
use crate::parse::context;
8+
9+
/// Parser for names given to things.
10+
pub fn parse_name(x: &str, y: &mut context::Context, construct: &str) -> Result<String> {
11+
static IDENTIFIER_RE: once_cell::sync::Lazy<regex::Regex> =
12+
once_cell::sync::Lazy::new(|| regex::Regex::new("[a-zA-Z_][a-zA-Z0-9_\\.]*").unwrap());
13+
14+
if x.is_empty() {
15+
diagnostic!(
16+
y,
17+
Info,
18+
LinkDiscouragedName,
19+
"using the empty string as a {construct} name is not explicitly \
20+
illegal, but probably not a good idea"
21+
);
22+
} else if !IDENTIFIER_RE.is_match(x) {
23+
diagnostic!(
24+
y,
25+
Info,
26+
LinkDiscouragedName,
27+
"it is recommended for {construct} names to case-insensitively \
28+
match [a-z_][a-z0-9_]* for maximum compatibility"
29+
);
30+
} else if x.contains('.') {
31+
diagnostic!(
32+
y,
33+
Info,
34+
LinkDiscouragedName,
35+
"using periods within a {construct} name is not explicitly \
36+
illegal, but probably not a good idea, as they are also used as \
37+
namespace separators for dependencies"
38+
);
39+
}
40+
Ok(x.to_owned())
41+
}

rs/src/parse/extensions/simple/function_decls.rs renamed to rs/src/parse/extensions/simple/functions.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
use crate::input::yaml;
77
use crate::output::diagnostic::Result;
88
use crate::parse::context;
9-
use crate::parse::extensions::simple::builder;
9+
use crate::parse::extensions::simple::modules;
1010

1111
/// Parse a scalar function declaration.
1212
pub fn parse_scalar_function(
1313
_x: &yaml::Value,
1414
_y: &mut context::Context,
15-
_z: &mut builder::Builder,
15+
_z: &mut modules::Builder,
1616
) -> Result<()> {
1717
// TODO
1818
Ok(())
@@ -22,7 +22,7 @@ pub fn parse_scalar_function(
2222
pub fn parse_aggregate_function(
2323
_x: &yaml::Value,
2424
_y: &mut context::Context,
25-
_z: &mut builder::Builder,
25+
_z: &mut modules::Builder,
2626
) -> Result<()> {
2727
// TODO
2828
Ok(())

rs/src/parse/extensions/simple/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: Apache-2.0
22

3-
//! Module providing parse/validation functions for advanced extensions, i.e.
3+
//! Module providing parse/validation functions for simple extensions, i.e.
44
//! those based around YAML files.
55
66
use crate::input::proto::substrait;
@@ -10,12 +10,12 @@ use crate::output::extension::simple::module::Scope;
1010
use crate::output::type_system::data;
1111
use crate::parse::context;
1212

13-
mod builder;
13+
mod common;
1414
mod derivations;
15-
mod function_decls;
16-
mod type_decls;
17-
mod type_variation_decls;
18-
mod yaml;
15+
mod functions;
16+
mod modules;
17+
mod type_classes;
18+
mod type_variations;
1919

2020
/// Parse a user-defined name. Note that names are matched case-insensitively
2121
/// because we return the name as lowercase.
@@ -51,7 +51,7 @@ fn parse_simple_extension_yaml_uri_mapping(
5151
) -> Result<()> {
5252
// Parse the fields.
5353
let anchor = proto_primitive_field!(x, y, extension_uri_anchor, parse_anchor).1;
54-
let yaml_data = proto_primitive_field!(x, y, uri, yaml::parse_uri)
54+
let yaml_data = proto_primitive_field!(x, y, uri, modules::parse_uri)
5555
.1
5656
.unwrap();
5757

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,115 @@
11
// SPDX-License-Identifier: Apache-2.0
22

3-
//! Module providing parse/validation functions for parsing YAML extension
4-
//! files.
3+
//! Module providing a builder structure to be used while parsing a simple
4+
//! extension file.
55
66
use crate::input::yaml;
77
use crate::output::diagnostic::Result;
88
use crate::output::extension;
99
use crate::output::path;
1010
use crate::parse::context;
11-
use crate::parse::extensions::simple::builder;
12-
use crate::parse::extensions::simple::function_decls;
13-
use crate::parse::extensions::simple::type_decls;
14-
use crate::parse::extensions::simple::type_variation_decls;
11+
use crate::parse::extensions::simple::functions;
12+
use crate::parse::extensions::simple::modules;
13+
use crate::parse::extensions::simple::type_classes;
14+
use crate::parse::extensions::simple::type_variations;
1515
use crate::parse::traversal;
1616
use crate::util;
17+
use std::collections::HashMap;
1718
use std::sync::Arc;
1819

20+
#[derive(Clone, Debug, Default)]
21+
pub struct Builder {
22+
/// Map with references to dependencies.
23+
pub dependencies: HashMap<String, extension::simple::module::Reference>,
24+
25+
/// Namespace used for type classes defined in this extension and its
26+
/// dependencies.
27+
pub type_classes: extension::simple::type_class::NamespaceDefinition,
28+
29+
/// Namespace used for type variations defined in this extension and its
30+
/// dependencies.
31+
pub type_variations: extension::simple::type_variation::NamespaceDefinition,
32+
33+
/// Namespace used for functions defined in this extension and its
34+
/// dependencies. Both simple and compound names are registered.
35+
pub function_impls: extension::simple::function::NamespaceDefinition,
36+
}
37+
38+
impl From<Builder> for extension::simple::module::Definition {
39+
fn from(builder: Builder) -> Self {
40+
extension::simple::module::Definition {
41+
dependencies: builder.dependencies,
42+
type_classes: Arc::new(builder.type_classes),
43+
type_variations: Arc::new(builder.type_variations),
44+
function_impls: Arc::new(builder.function_impls),
45+
}
46+
}
47+
}
48+
49+
impl extension::simple::module::Scope for Builder {
50+
/// Resolves a to-be-resolved reference to a type class.
51+
fn resolve_type_class<T>(&self, name: T) -> extension::simple::type_class::ResolutionResult
52+
where
53+
T: Into<extension::simple::type_class::UnresolvedReference>,
54+
{
55+
self.type_classes.resolve_local(name.into())
56+
}
57+
58+
/// Resolves a to-be-resolved reference to a type variation.
59+
fn resolve_type_variation<T>(
60+
&self,
61+
name: T,
62+
) -> extension::simple::type_variation::ResolutionResult
63+
where
64+
T: Into<extension::simple::type_variation::UnresolvedReference>,
65+
{
66+
self.type_variations.resolve_local(name.into())
67+
}
68+
69+
/// Resolves a to-be-resolved reference to a function.
70+
fn resolve_function<T>(&self, name: T) -> extension::simple::function::ResolutionResult
71+
where
72+
T: Into<extension::simple::function::UnresolvedReference>,
73+
{
74+
self.function_impls.resolve_local(name.into())
75+
}
76+
}
77+
1978
/// Toplevel parse function for a simple extension YAML file.
2079
fn parse_root(
2180
x: &yaml::Value,
2281
y: &mut context::Context,
2382
) -> Result<extension::simple::module::Definition> {
24-
let mut builder = builder::Builder::default();
25-
yaml_repeated_field!(x, y, "types", type_decls::parse_type, 0, &mut builder)?;
83+
let mut builder = modules::Builder::default();
84+
yaml_repeated_field!(
85+
x,
86+
y,
87+
"types",
88+
type_classes::parse_type_class,
89+
0,
90+
&mut builder
91+
)?;
2692
yaml_repeated_field!(
2793
x,
2894
y,
2995
"type_variations",
30-
type_variation_decls::parse_type_variation,
96+
type_variations::parse_type_variation,
3197
0,
3298
&mut builder
3399
)?;
34100
yaml_repeated_field!(
35101
x,
36102
y,
37103
"scalar_functions",
38-
function_decls::parse_scalar_function,
104+
functions::parse_scalar_function,
39105
0,
40106
&mut builder
41107
)?;
42108
yaml_repeated_field!(
43109
x,
44110
y,
45111
"aggregate_functions",
46-
function_decls::parse_aggregate_function,
112+
functions::parse_aggregate_function,
47113
0,
48114
&mut builder
49115
)?;

0 commit comments

Comments
 (0)