Skip to content

Commit

Permalink
feat: add literal type default value pass and preprocess (#1583)
Browse files Browse the repository at this point in the history
Signed-off-by: peefy <[email protected]>
  • Loading branch information
Peefy committed Aug 19, 2024
1 parent 24dafd8 commit 2a36798
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 10 deletions.
10 changes: 4 additions & 6 deletions kclvm/ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1347,15 +1347,13 @@ pub struct StringLit {
}

/// Generate ast.StringLit from String
impl TryFrom<String> for StringLit {
type Error = &'static str;

fn try_from(value: String) -> Result<Self, Self::Error> {
Ok(Self {
impl From<String> for StringLit {
fn from(value: String) -> Self {
Self {
value: value.clone(),
raw_value: format!("{:?}", value),
is_long_string: false,
})
}
}
}

Expand Down
7 changes: 4 additions & 3 deletions kclvm/sema/src/pre_process/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl<'ctx> MutSelfMutWalker<'ctx> for ConfigNestAttrTransformer {
}
}

#[derive(Debug)]
#[derive(Debug, Default)]
struct ConfigMergeTransformer {}

#[derive(Debug)]
Expand Down Expand Up @@ -355,9 +355,10 @@ fn unify_config_entries(
entries
}

/// Merge program
/// Merge program for multiple file config.
#[inline]
pub fn merge_program(program: &mut ast::Program) {
let mut merger = ConfigMergeTransformer {};
let mut merger = ConfigMergeTransformer::default();
merger.merge(program);
}

Expand Down
1 change: 1 addition & 0 deletions kclvm/sema/src/pre_process/identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ pub fn fix_qualified_identifier<'ctx>(
}

/// Fix AST raw identifier prefix `$`, e.g., $filter -> filter
#[inline]
pub fn fix_raw_identifier_prefix(module: &'_ mut ast::Module) {
RawIdentifierTransformer::default().walk_module(module);
}
89 changes: 89 additions & 0 deletions kclvm/sema/src/pre_process/lit_ty_default_value.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use kclvm_ast::ast;
use kclvm_ast::walker::MutSelfMutWalker;

#[derive(Default)]
struct LitTypeDefaultValueTransformer;

impl<'ctx> MutSelfMutWalker<'ctx> for LitTypeDefaultValueTransformer {
fn walk_schema_attr(&mut self, schema_attr: &'ctx mut ast::SchemaAttr) {
if schema_attr.value.is_none() && !schema_attr.is_optional {
if let ast::Type::Literal(literal_ty) = &schema_attr.ty.node {
let filename = schema_attr.ty.filename.clone();
let line = schema_attr.ty.end_line;
// Append ` = ` width for th column.
let column = schema_attr.ty.end_column + 3;
schema_attr.op = Some(ast::AugOp::Assign);
match literal_ty {
ast::LiteralType::Bool(val) => {
let column_offset = if *val { 4 } else { 5 };
schema_attr.value = Some(Box::new(ast::Node::new(
ast::Expr::NameConstantLit(ast::NameConstantLit {
value: if *val {
ast::NameConstant::True
} else {
ast::NameConstant::False
},
}),
filename,
line,
column,
line,
column + column_offset,
)));
}
ast::LiteralType::Int(val) => {
let value = val.value.to_string();
let mut column_offset = value.len() as u64;
if let Some(suffix) = &val.suffix {
column_offset += suffix.value().len() as u64
}
schema_attr.value = Some(Box::new(ast::Node::new(
ast::Expr::NumberLit(ast::NumberLit {
binary_suffix: val.suffix.clone(),
value: ast::NumberLitValue::Int(val.value),
}),
filename,
line,
column,
line,
column + column_offset,
)));
}
ast::LiteralType::Float(val) => {
let value = kclvm_runtime::float_to_string(*val);
let column_offset = value.len() as u64;
schema_attr.value = Some(Box::new(ast::Node::new(
ast::Expr::NumberLit(ast::NumberLit {
binary_suffix: None,
value: ast::NumberLitValue::Float(*val),
}),
filename,
line,
column,
line,
column + column_offset,
)));
}
ast::LiteralType::Str(val) => {
let value: ast::StringLit = val.to_string().into();
let column_offset = value.raw_value.len() as u64;
schema_attr.value = Some(Box::new(ast::Node::new(
ast::Expr::StringLit(value),
filename,
line,
column,
line,
column + column_offset,
)));
}
}
}
}
}
}

/// Fix literal type default value. e.g., `a: "value"` -> `a: "value" = "value"`.
#[inline]
pub fn fix_lit_ty_default_value(module: &'_ mut ast::Module) {
LitTypeDefaultValueTransformer::default().walk_module(module);
}
3 changes: 3 additions & 0 deletions kclvm/sema/src/pre_process/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod config;
mod identifier;
mod lit_ty_default_value;
mod multi_assign;

use indexmap::IndexMap;
Expand All @@ -10,6 +11,7 @@ mod tests;

pub use config::{fix_config_expr_nest_attr, merge_program};
pub use identifier::{fix_qualified_identifier, fix_raw_identifier_prefix};
pub use lit_ty_default_value::fix_lit_ty_default_value;
pub use multi_assign::transform_multi_assign;

use crate::resolver::Options;
Expand All @@ -36,6 +38,7 @@ pub fn pre_process_program(program: &mut ast::Program, opts: &Options) {
fix_raw_identifier_prefix(module);
fix_qualified_identifier(module, &mut import_names);
fix_config_expr_nest_attr(module);
fix_lit_ty_default_value(module);
}
}
if opts.merge_program {
Expand Down
7 changes: 7 additions & 0 deletions kclvm/sema/src/pre_process/test_data/lit_ty_default_val.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
schema LitTyConfig:
val0: "val"
val1: 1
val2: 1Ki
val3: 2.0
val4: True
val5: False
76 changes: 76 additions & 0 deletions kclvm/sema/src/pre_process/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,82 @@ fn test_fix_qualified_identifier() {
}
}

#[test]
fn test_fix_lit_ty_default_value() {
let mut module =
parse_file_force_errors("./src/pre_process/test_data/lit_ty_default_val.k", None).unwrap();
fix_lit_ty_default_value(&mut module);
if let ast::Stmt::Schema(schema_stmt) = &module.body[0].node {
if let ast::Stmt::SchemaAttr(schema_attr) = &schema_stmt.body[0].node {
assert_eq!(
schema_attr.value.as_ref().unwrap().node,
ast::Expr::StringLit(ast::StringLit {
is_long_string: false,
raw_value: "\"val\"".to_string(),
value: "val".to_string(),
})
)
} else {
panic!("invalid schema attr value")
}
if let ast::Stmt::SchemaAttr(schema_attr) = &schema_stmt.body[1].node {
assert_eq!(
schema_attr.value.as_ref().unwrap().node,
ast::Expr::NumberLit(ast::NumberLit {
value: ast::NumberLitValue::Int(1),
binary_suffix: None,
})
)
} else {
panic!("invalid schema attr value")
}
if let ast::Stmt::SchemaAttr(schema_attr) = &schema_stmt.body[2].node {
assert_eq!(
schema_attr.value.as_ref().unwrap().node,
ast::Expr::NumberLit(ast::NumberLit {
value: ast::NumberLitValue::Int(1),
binary_suffix: Some(ast::NumberBinarySuffix::Ki),
})
)
} else {
panic!("invalid schema attr value")
}
if let ast::Stmt::SchemaAttr(schema_attr) = &schema_stmt.body[3].node {
assert_eq!(
schema_attr.value.as_ref().unwrap().node,
ast::Expr::NumberLit(ast::NumberLit {
value: ast::NumberLitValue::Float(2.0),
binary_suffix: None,
})
)
} else {
panic!("invalid schema attr value")
}
if let ast::Stmt::SchemaAttr(schema_attr) = &schema_stmt.body[4].node {
assert_eq!(
schema_attr.value.as_ref().unwrap().node,
ast::Expr::NameConstantLit(ast::NameConstantLit {
value: ast::NameConstant::True,
})
)
} else {
panic!("invalid schema attr value")
}
if let ast::Stmt::SchemaAttr(schema_attr) = &schema_stmt.body[5].node {
assert_eq!(
schema_attr.value.as_ref().unwrap().node,
ast::Expr::NameConstantLit(ast::NameConstantLit {
value: ast::NameConstant::False,
})
)
} else {
panic!("invalid schema attr value")
}
} else {
panic!("invalid schema statement")
}
}

#[test]
fn test_fix_raw_identifier_prefix() {
let mut module =
Expand Down
8 changes: 7 additions & 1 deletion kclvm/sema/src/resolver/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,13 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> {
None,
),
},
None => bug!("invalid ast schema attr op kind"),
// Default is Assign
None => self.must_assignable_to(
value_ty,
expected_ty,
schema_attr.name.get_span_pos(),
None,
),
}
}
self.any_ty()
Expand Down
9 changes: 9 additions & 0 deletions test/grammar/schema/default_value/default_value_3/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
schema Config:
val0: "val"
val1: 1
val2: 1Ki
val3: 2.0
val4: True
val5: False

c = Config {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
c:
val0: val
val1: 1
val2: 1024.0
val3: 2.0
val4: true
val5: false

0 comments on commit 2a36798

Please sign in to comment.