Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion debugger/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ fn expr_to_artifact_value(expr: &Expr<'_>) -> Result<ArtifactValue, String> {
ExprKind::Bool(value) => Ok(ArtifactValue::Bool(*value)),
ExprKind::Byte(value) => Ok(ArtifactValue::Byte(*value)),
ExprKind::String(value) => Ok(ArtifactValue::Text(value.clone())),
ExprKind::Array { type_ref, values } if matches!(type_ref.base, TypeBase::Byte) && type_ref.array_dims.len() == 1 => {
ExprKind::Array { type_ref, values, .. } if matches!(type_ref.base, TypeBase::Byte) && type_ref.array_dims.len() == 1 => {
let bytes = values
.iter()
.map(|value| match value.kind {
Expand Down
8 changes: 6 additions & 2 deletions debugger/session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2178,8 +2178,12 @@ where
},
span,
)),
ExprKind::Array { type_ref, values } => Ok(Expr::new(
ExprKind::Array { type_ref: type_ref.clone(), values: values.iter().map(&mut *map_child).collect::<Result<Vec<_>, _>>()? },
ExprKind::Array { type_ref, values, type_span } => Ok(Expr::new(
ExprKind::Array {
type_ref: type_ref.clone(),
values: values.iter().map(&mut *map_child).collect::<Result<Vec<_>, _>>()?,
type_span: *type_span,
},
span,
)),
ExprKind::StructLiteral { name, fields, name_span } => Ok(Expr::new(
Expand Down
76 changes: 53 additions & 23 deletions silverscript-lang/src/ast/mod.rs

Large diffs are not rendered by default.

84 changes: 77 additions & 7 deletions silverscript-lang/src/ast/visit.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
use super::{
ConstantAst, ContractAst, ContractFieldAst, Expr, ExprKind, FunctionAst, FunctionAttributeArgAst, FunctionAttributeAst, ParamAst,
Statement, StructBindingAst,
Statement, StructAst, StructBindingAst, StructFieldAst, TypeBase, TypeRef,
};
use crate::span::Span;

fn visit_type_ref<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, type_ref: &TypeRef, span: Span<'i>) {
visitor.visit_type(type_ref, span);
}

fn visit_struct_type_name<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, name: &str, span: Span<'i>) {
let type_ref = TypeRef { base: TypeBase::Custom(name.to_string()), array_dims: Vec::new() };
visitor.visit_type(&type_ref, span);
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NameKind {
Contract,
Struct,
StructField,
ContractField,
Constant,
Function,
Expand All @@ -25,6 +36,14 @@ pub enum NameKind {
pub trait AstVisitorMut<'i> {
/// Visits a classified name together with its exact source span.
fn visit_name(&mut self, _name: &mut String, _kind: NameKind, _span: Span<'i>) {}
/// Visits a classified type. For parsed ASTs, its base type name starts at
/// `span.start()`.
fn visit_type(&mut self, _type_ref: &TypeRef, _span: Span<'i>) {}
/// Visits a stored source span without classifying what it belongs to.
///
/// The span is mutable so visitors can relocate or reset every span reached
/// by the walker, for example after embedding a parsed fragment at a source
/// offset. Synthetic AST nodes may carry an empty `Span::default()` value.
fn visit_span(&mut self, _span: &mut Span<'i>) {}

fn visit_contract(&mut self, contract: &mut ContractAst<'i>) {
Expand All @@ -35,6 +54,14 @@ pub trait AstVisitorMut<'i> {
walk_contract_field_mut(self, field);
}

fn visit_struct(&mut self, item: &mut StructAst<'i>) {
walk_struct_mut(self, item);
}

fn visit_struct_field(&mut self, field: &mut StructFieldAst<'i>) {
walk_struct_field_mut(self, field);
}

fn visit_constant(&mut self, constant: &mut ConstantAst<'i>) {
walk_constant_mut(self, constant);
}
Expand Down Expand Up @@ -83,6 +110,9 @@ pub fn walk_contract_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, con
for param in &mut contract.params {
visitor.visit_param(param);
}
for item in &mut contract.structs {
visitor.visit_struct(item);
}
for field in &mut contract.fields {
visitor.visit_contract_field(field);
}
Expand All @@ -94,7 +124,25 @@ pub fn walk_contract_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, con
}
}

pub fn walk_struct_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, item: &mut StructAst<'i>) {
visitor.visit_name(&mut item.name, NameKind::Struct, item.name_span);
visitor.visit_span(&mut item.span);
visitor.visit_span(&mut item.name_span);
for field in &mut item.fields {
visitor.visit_struct_field(field);
}
}

pub fn walk_struct_field_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, field: &mut StructFieldAst<'i>) {
visit_type_ref(visitor, &field.type_ref, field.type_span);
visitor.visit_name(&mut field.name, NameKind::StructField, field.name_span);
visitor.visit_span(&mut field.span);
visitor.visit_span(&mut field.type_span);
visitor.visit_span(&mut field.name_span);
}

pub fn walk_contract_field_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, field: &mut ContractFieldAst<'i>) {
visit_type_ref(visitor, &field.type_ref, field.type_span);
visitor.visit_name(&mut field.name, NameKind::ContractField, field.name_span);
visitor.visit_span(&mut field.span);
visitor.visit_span(&mut field.type_span);
Expand All @@ -103,6 +151,7 @@ pub fn walk_contract_field_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut
}

pub fn walk_constant_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, constant: &mut ConstantAst<'i>) {
visit_type_ref(visitor, &constant.type_ref, constant.type_span);
visitor.visit_name(&mut constant.name, NameKind::Constant, constant.name_span);
visitor.visit_span(&mut constant.span);
visitor.visit_span(&mut constant.type_span);
Expand All @@ -115,6 +164,11 @@ pub fn walk_function_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, fun
visitor.visit_span(&mut function.span);
visitor.visit_span(&mut function.name_span);
visitor.visit_span(&mut function.body_span);
for (type_ref, span) in
function.return_types.iter().zip(function.return_type_spans.iter().copied().chain(std::iter::repeat(Span::default())))
{
visit_type_ref(visitor, type_ref, span);
}
for span in &mut function.return_type_spans {
visitor.visit_span(span);
}
Expand All @@ -131,7 +185,9 @@ pub fn walk_function_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, fun

pub fn walk_function_attribute_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, attribute: &mut FunctionAttributeAst<'i>) {
visitor.visit_span(&mut attribute.span);
for (segment, span) in attribute.path.iter_mut().zip(attribute.path_spans.iter().copied()) {
for (segment, span) in
attribute.path.iter_mut().zip(attribute.path_spans.iter().copied().chain(std::iter::repeat(Span::default())))
{
visitor.visit_name(segment, NameKind::AttributePathSegment, span);
}
for span in &mut attribute.path_spans {
Expand All @@ -154,13 +210,15 @@ pub fn walk_param_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, param:
}

fn walk_param_with_kind_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, param: &mut ParamAst<'i>, kind: NameKind) {
visit_type_ref(visitor, &param.type_ref, param.type_span);
visitor.visit_name(&mut param.name, kind, param.name_span);
visitor.visit_span(&mut param.span);
visitor.visit_span(&mut param.type_span);
visitor.visit_span(&mut param.name_span);
}

pub fn walk_state_binding_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, binding: &mut StructBindingAst<'i>) {
visit_type_ref(visitor, &binding.type_ref, binding.type_span);
visitor.visit_name(&mut binding.field_name, NameKind::StateField, binding.field_span);
visitor.visit_name(&mut binding.name, NameKind::StateBinding, binding.name_span);
visitor.visit_span(&mut binding.span);
Expand All @@ -171,7 +229,8 @@ pub fn walk_state_binding_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V

pub fn walk_statement_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, statement: &mut Statement<'i>) {
match statement {
Statement::VariableDefinition { name, expr, span, type_span, modifier_spans, name_span, .. } => {
Statement::VariableDefinition { type_ref, name, expr, span, type_span, modifier_spans, name_span, .. } => {
visit_type_ref(visitor, type_ref, *type_span);
visitor.visit_name(name, NameKind::LocalBinding, *name_span);
visitor.visit_span(span);
visitor.visit_span(type_span);
Expand All @@ -185,7 +244,9 @@ pub fn walk_statement_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, st
}
Statement::TupleAssignment {
left_name,
left_type_ref,
right_name,
right_type_ref,
expr,
span,
left_type_span,
Expand All @@ -194,6 +255,8 @@ pub fn walk_statement_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, st
right_name_span,
..
} => {
visit_type_ref(visitor, left_type_ref, *left_type_span);
visit_type_ref(visitor, right_type_ref, *right_type_span);
visitor.visit_name(left_name, NameKind::LocalBinding, *left_name_span);
visitor.visit_name(right_name, NameKind::LocalBinding, *right_name_span);
visitor.visit_span(span);
Expand Down Expand Up @@ -222,9 +285,11 @@ pub fn walk_statement_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, st
visitor.visit_expr(arg);
}
}
Statement::StateFunctionCallAssign { target_struct: _, bindings, name, args, span, name_span } => {
Statement::StateFunctionCallAssign { target_struct, bindings, name, args, span, target_struct_span, name_span } => {
visit_struct_type_name(visitor, target_struct, *target_struct_span);
visitor.visit_name(name, NameKind::CallTarget, *name_span);
visitor.visit_span(span);
visitor.visit_span(target_struct_span);
visitor.visit_span(name_span);
for binding in bindings {
visitor.visit_state_binding(binding);
Expand All @@ -233,8 +298,10 @@ pub fn walk_statement_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, st
visitor.visit_expr(arg);
}
}
Statement::StructDestructure { bindings, expr, span, .. } => {
Statement::StructDestructure { struct_name, bindings, expr, span, struct_name_span } => {
visit_struct_type_name(visitor, struct_name, *struct_name_span);
visitor.visit_span(span);
visitor.visit_span(struct_name_span);
for binding in bindings {
visitor.visit_state_binding(binding);
}
Expand Down Expand Up @@ -317,7 +384,9 @@ pub fn walk_expr_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, expr: &
visitor.visit_span(&mut expr.span);
match &mut expr.kind {
ExprKind::Identifier(name) => visitor.visit_name(name, NameKind::IdentifierExpr, expr_span),
ExprKind::Array { values: items, .. } => {
ExprKind::Array { type_ref, values: items, type_span } => {
visit_type_ref(visitor, type_ref, *type_span);
visitor.visit_span(type_span);
for item in items {
visitor.visit_expr(item);
}
Expand Down Expand Up @@ -371,7 +440,8 @@ pub fn walk_expr_mut<'i, V: AstVisitorMut<'i> + ?Sized>(visitor: &mut V, expr: &
visitor.visit_span(field_span);
visitor.visit_expr(index);
}
ExprKind::StructLiteral { fields, name_span, .. } => {
ExprKind::StructLiteral { name, fields, name_span } => {
visit_struct_type_name(visitor, name, *name_span);
visitor.visit_span(name_span);
for field in fields {
visitor.visit_name(&mut field.name, NameKind::StateField, field.name_span);
Expand Down
12 changes: 8 additions & 4 deletions silverscript-lang/src/compiler/array_append.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ fn lower_statement<'i>(
name_span: *name_span,
})
}
Statement::StateFunctionCallAssign { target_struct, bindings, name, args, span, name_span } => {
Statement::StateFunctionCallAssign { target_struct, bindings, name, args, span, target_struct_span, name_span } => {
let lowered_args = args.iter().map(|arg| lower_expr(arg, types, constants, functions)).collect::<Result<Vec<_>, _>>()?;
for binding in bindings {
types.insert(binding.name.clone(), binding.type_ref.clone());
Expand All @@ -157,10 +157,11 @@ fn lower_statement<'i>(
name: name.clone(),
args: lowered_args,
span: *span,
target_struct_span: *target_struct_span,
name_span: *name_span,
})
}
Statement::StructDestructure { struct_name, bindings, expr, span } => {
Statement::StructDestructure { struct_name, bindings, expr, span, struct_name_span } => {
let lowered_expr = lower_expr(expr, types, constants, functions)?;
for binding in bindings {
types.insert(binding.name.clone(), binding.type_ref.clone());
Expand All @@ -170,6 +171,7 @@ fn lower_statement<'i>(
bindings: bindings.clone(),
expr: lowered_expr,
span: *span,
struct_name_span: *struct_name_span,
})
}
Statement::Assign { name, expr, span, name_span } => Ok(Statement::Assign {
Expand Down Expand Up @@ -279,17 +281,19 @@ fn lower_expr<'i>(
.iter()
.map(|arg| lower_expr(arg, types, constants, functions))
.collect::<Result<Vec<_>, _>>()?,
type_span: span::Span::default(),
},
span::Span::default(),
)),
},
span,
))
}
ExprKind::Array { type_ref, values } => Ok(Expr::new(
ExprKind::Array { type_ref, values, type_span } => Ok(Expr::new(
ExprKind::Array {
type_ref: type_ref.clone(),
values: values.iter().map(|value| lower_expr(value, types, constants, functions)).collect::<Result<Vec<_>, _>>()?,
type_span: *type_span,
},
span,
)),
Expand Down Expand Up @@ -423,7 +427,7 @@ mod tests {
let ExprKind::Binary { op: BinaryOp::Add, right, .. } = &expr.kind else {
panic!("append should lower to addition");
};
let ExprKind::Array { type_ref, values } = &right.kind else {
let ExprKind::Array { type_ref, values, .. } = &right.kind else {
panic!("append arguments should lower to an array");
};

Expand Down
4 changes: 2 additions & 2 deletions silverscript-lang/src/compiler/compile/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,12 @@ pub(crate) fn resolve_constant_references<'i>(
},
span,
)),
ExprKind::Array { type_ref, values } => {
ExprKind::Array { type_ref, values, type_span } => {
let mut resolved = Vec::with_capacity(values.len());
for value in values {
resolved.push(resolve_constant_references(value, constants, visiting)?);
}
Ok(Expr::new(ExprKind::Array { type_ref: type_ref.clone(), values: resolved }, span))
Ok(Expr::new(ExprKind::Array { type_ref: type_ref.clone(), values: resolved, type_span }, span))
}
ExprKind::StructLiteral { name, fields, name_span } => {
let mut resolved_fields = Vec::with_capacity(fields.len());
Expand Down
2 changes: 1 addition & 1 deletion silverscript-lang/src/compiler/compile/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fn compile_expr_with_context<'i>(
ExprKind::Int(value) | ExprKind::Temporal(value) => compile_int_expr(ctx, *value, expected_type),
ExprKind::Bool(value) => compile_bool_expr(ctx, *value),
ExprKind::Byte(byte) => compile_byte_expr(ctx, *byte),
ExprKind::Array { type_ref, values } => compile_array_expr(ctx, values, Some(type_ref)),
ExprKind::Array { type_ref, values, .. } => compile_array_expr(ctx, values, Some(type_ref)),
ExprKind::StructLiteral { .. } => compile_state_object_expr(),
ExprKind::FieldAccess { .. } => compile_field_access_expr(),
ExprKind::String(value) => compile_string_expr(ctx, value),
Expand Down
11 changes: 7 additions & 4 deletions silverscript-lang/src/compiler/debug_recording.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,11 @@ impl<'i> DebugRecorder<'i> {
let span = expr.span;
let kind = match expr.kind {
ExprKind::Identifier(name) => ExprKind::Identifier(self.visible_name(&name)),
ExprKind::Array { type_ref, values } => {
ExprKind::Array { type_ref, values: values.into_iter().map(|value| self.rewrite_debug_expr(value)).collect() }
}
ExprKind::Array { type_ref, values, type_span } => ExprKind::Array {
type_ref,
values: values.into_iter().map(|value| self.rewrite_debug_expr(value)).collect(),
type_span,
},
ExprKind::Call { name, args, name_span } => {
ExprKind::Call { name, args: args.into_iter().map(|arg| self.rewrite_debug_expr(arg)).collect(), name_span }
}
Expand Down Expand Up @@ -522,12 +524,13 @@ fn rewrite_debug_expr_with_function<'i>(

let kind = match expr.kind {
ExprKind::Identifier(name) => ExprKind::Identifier(visible_name(&name)),
ExprKind::Array { type_ref, values } => ExprKind::Array {
ExprKind::Array { type_ref, values, type_span } => ExprKind::Array {
type_ref,
values: values
.into_iter()
.map(|value| rewrite_debug_expr_with_function(value, function_name, visible_names_by_function))
.collect(),
type_span,
},
ExprKind::Call { name, args, name_span } => ExprKind::Call {
name,
Expand Down
10 changes: 6 additions & 4 deletions silverscript-lang/src/compiler/inline_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ impl<'i, 'd> Inliner<'i, 'd> {
);
}
}
Statement::StateFunctionCallAssign { target_struct, bindings, name, args, span, name_span } => {
Statement::StateFunctionCallAssign { target_struct, bindings, name, args, span, target_struct_span, name_span } => {
let (prelude, renamed_args) = self.lower_exprs(args, scope, visited_functions)?;
lowered.extend(prelude);
let renamed_bindings = bindings
Expand All @@ -223,11 +223,12 @@ impl<'i, 'd> Inliner<'i, 'd> {
name: name.clone(),
args: renamed_args,
span: *span,
target_struct_span: *target_struct_span,
name_span: *name_span,
},
);
}
Statement::StructDestructure { struct_name, bindings, expr, span } => {
Statement::StructDestructure { struct_name, bindings, expr, span, struct_name_span } => {
let (prelude, renamed_expr) = self.lower_expr(expr, scope, visited_functions)?;
lowered.extend(prelude);
let renamed_bindings = bindings
Expand All @@ -244,6 +245,7 @@ impl<'i, 'd> Inliner<'i, 'd> {
bindings: renamed_bindings,
expr: renamed_expr,
span: *span,
struct_name_span: *struct_name_span,
},
);
}
Expand Down Expand Up @@ -506,9 +508,9 @@ impl<'i, 'd> Inliner<'i, 'd> {
ExprKind::String(value) => Ok((Vec::new(), Expr::new(ExprKind::String(value.clone()), span))),
ExprKind::DateLiteral(value) => Ok((Vec::new(), Expr::new(ExprKind::DateLiteral(*value), span))),
ExprKind::Identifier(name) => Ok((Vec::new(), Expr::new(ExprKind::Identifier(self.rename_name(name, scope)), span))),
ExprKind::Array { type_ref, values } => {
ExprKind::Array { type_ref, values, type_span } => {
let (prelude, values) = self.lower_exprs(values, scope, visited_functions)?;
Ok((prelude, Expr::new(ExprKind::Array { type_ref: type_ref.clone(), values }, span)))
Ok((prelude, Expr::new(ExprKind::Array { type_ref: type_ref.clone(), values, type_span: *type_span }, span)))
}
ExprKind::Call { name, args, name_span } => {
let (mut prelude, args) = self.lower_exprs(args, scope, visited_functions)?;
Expand Down
Loading