Skip to content
This repository has been archived by the owner on Nov 4, 2024. It is now read-only.

Changes for the language server #254

Merged
merged 20 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from 18 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
147 changes: 92 additions & 55 deletions src/compiler/semantic/analyser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,7 @@ impl Analyser {
output_params,
block,
} => {
let sym = SymTableEntry {
definition_ref: dsym,
category: SymbolCategory::Machine,
ty: None,
};
let sym = SymTableEntry::new(id.name(), dsym, SymbolCategory::Machine, None);

RULES.apply_new_symbol_tldecl(self, decl, &id, &sym);

Expand Down Expand Up @@ -98,22 +94,24 @@ impl Analyser {
fn analyse_machine_input_params(&mut self, params: Vec<Statement<BigInt, Identifier>>) {
params.iter().for_each(|param| match param {
Statement::SignalDecl(dsym, ids) => ids.iter().for_each(|id| {
let sym = SymTableEntry {
definition_ref: dsym.clone(),
category: SymbolCategory::InputSignal,
ty: id.ty.clone().map(|ty| ty.name()),
};
let sym = SymTableEntry::new(
id.id.name(),
dsym.clone(),
SymbolCategory::InputSignal,
id.ty.clone().map(|ty| ty.name()),
);

RULES.apply_new_symbol_statement(self, param, &id.id, &sym);

self.symbols.add_symbol(&self.cur_scope, id.id.name(), sym);
}),
Statement::WGVarDecl(dsym, ids) => ids.iter().for_each(|id| {
let sym = SymTableEntry {
definition_ref: dsym.clone(),
category: SymbolCategory::InputWGVar,
ty: id.ty.clone().map(|ty| ty.name()),
};
let sym = SymTableEntry::new(
id.id.name(),
dsym.clone(),
SymbolCategory::InputWGVar,
id.ty.clone().map(|ty| ty.name()),
);

RULES.apply_new_symbol_statement(self, param, &id.id, &sym);

Expand All @@ -126,23 +124,25 @@ impl Analyser {
fn analyse_machine_output_params(&mut self, params: Vec<Statement<BigInt, Identifier>>) {
params.iter().for_each(|param| match param {
Statement::SignalDecl(dsym, ids) => ids.iter().for_each(|id| {
let sym = SymTableEntry {
definition_ref: dsym.clone(),
category: SymbolCategory::OutputSignal,
ty: id.ty.clone().map(|ty| ty.name()),
};
let sym = SymTableEntry::new(
id.id.name(),
dsym.clone(),
SymbolCategory::OutputSignal,
id.ty.clone().map(|ty| ty.name()),
);

RULES.apply_new_symbol_statement(self, param, &id.id, &sym);

self.symbols
.add_output_variable(&self.cur_scope, id.id.name(), sym);
}),
Statement::WGVarDecl(dsym, ids) => ids.iter().for_each(|id| {
let sym = SymTableEntry {
definition_ref: dsym.clone(),
category: SymbolCategory::OutputWGVar,
ty: id.ty.clone().map(|ty| ty.name()),
};
let sym = SymTableEntry::new(
id.id.name(),
dsym.clone(),
SymbolCategory::OutputWGVar,
id.ty.clone().map(|ty| ty.name()),
);

RULES.apply_new_symbol_statement(self, param, &id.id, &sym);

Expand All @@ -161,11 +161,8 @@ impl Analyser {
if let Statement::Block(_, stmts) = block {
stmts.iter().for_each(|stmt| {
if let Statement::StateDecl(dsym, id, _) = stmt {
let sym = SymTableEntry {
definition_ref: dsym.clone(),
category: SymbolCategory::State,
ty: None,
};
let sym =
SymTableEntry::new(id.name(), dsym.clone(), SymbolCategory::State, None);

RULES.apply_new_symbol_statement(self, stmt, id, &sym);

Expand All @@ -181,18 +178,14 @@ impl Analyser {
.get_symbol(&self.cur_scope, "final".to_string())
.is_none()
{
let id = Identifier("final".to_string(), 0);
let id = Identifier("final".to_string(), 0, block.get_dsym());
let stmt = Statement::StateDecl(
block.get_dsym(),
id.clone(),
Box::new(Statement::Block(block.get_dsym(), vec![])),
);

let sym = SymTableEntry {
definition_ref: block.get_dsym(),
category: SymbolCategory::State,
ty: None,
};
let sym = SymTableEntry::new(id.name(), block.get_dsym(), SymbolCategory::State, None);

RULES.apply_new_symbol_statement(self, &stmt, &id, &sym);

Expand All @@ -219,22 +212,24 @@ impl Analyser {
fn statement_add_symbols(&mut self, stmt: &Statement<BigInt, Identifier>) {
match stmt.clone() {
Statement::SignalDecl(dsym, ids) => ids.into_iter().for_each(|id| {
let sym = SymTableEntry {
category: SymbolCategory::Signal,
definition_ref: dsym.clone(),
ty: id.ty.map(|ty| ty.name()),
};
let sym = SymTableEntry::new(
id.id.name(),
dsym.clone(),
SymbolCategory::Signal,
id.ty.map(|ty| ty.name()),
);

RULES.apply_new_symbol_statement(self, stmt, &id.id, &sym);

self.symbols.add_symbol(&self.cur_scope, id.id.name(), sym);
}),
Statement::WGVarDecl(dsym, ids) => ids.into_iter().for_each(|id| {
let sym = SymTableEntry {
category: SymbolCategory::WGVar,
definition_ref: dsym.clone(),
ty: id.ty.map(|ty| ty.name()),
};
let sym = SymTableEntry::new(
id.id.name(),
dsym.clone(),
SymbolCategory::WGVar,
id.ty.map(|ty| ty.name()),
);

RULES.apply_new_symbol_statement(self, stmt, &id.id, &sym);

Expand All @@ -250,12 +245,18 @@ impl Analyser {
fn analyse_statement_recursive(&mut self, stmt: Statement<BigInt, Identifier>) {
match stmt {
Statement::Assert(_, expr) => self.analyse_expression(expr),
Statement::SignalAssignment(_, _, exprs) => exprs
.into_iter()
.for_each(|expr| self.analyse_expression(expr)),
Statement::SignalAssignmentAssert(_, _, exprs) => exprs
.into_iter()
.for_each(|expr| self.analyse_expression(expr)),
Statement::SignalAssignment(_, ids, exprs) => {
exprs
.into_iter()
.for_each(|expr| self.analyse_expression(expr));
self.collect_id_usages(&ids);
}
Statement::SignalAssignmentAssert(_, ids, exprs) => {
exprs
.into_iter()
.for_each(|expr| self.analyse_expression(expr));
self.collect_id_usages(&ids);
}
Statement::WGAssignment(_, _, exprs) => exprs
.into_iter()
.for_each(|expr| self.analyse_expression(expr)),
Expand All @@ -270,7 +271,10 @@ impl Analyser {
}

Statement::StateDecl(_, id, block) => self.analyse_state(id, *block),
Statement::Transition(_, _, block) => self.analyse_statement(*block),
Statement::Transition(_, id, block) => {
self.analyse_statement(*block);
self.collect_id_usages(&[id]);
}

Statement::Block(_, stmts) => stmts
.into_iter()
Expand All @@ -282,7 +286,40 @@ impl Analyser {
}

fn analyse_expression(&mut self, expr: Expression<BigInt, Identifier>) {
RULES.apply_expression(self, &expr)
RULES.apply_expression(self, &expr);
self.extract_usages_expression(&expr);
}

fn collect_id_usages(&mut self, ids: &[Identifier]) {
for id in ids {
self.symbols
.add_symbol_usage(&self.cur_scope, id.name(), id.debug_sym_ref());
}
}

fn extract_usages_expression(&mut self, expr: &Expression<BigInt, Identifier>) {
match expr.clone() {
Expression::Query(_, id) => {
self.collect_id_usages(&[id]);
}
Expression::BinOp {
dsym: _,
op: _,
lhs,
rhs,
} => {
self.extract_usages_expression(&lhs);
self.extract_usages_expression(&rhs);
}
Expression::UnaryOp {
dsym: _,
op: _,
sub,
} => {
self.extract_usages_expression(&sub);
}
_ => {}
}
}

pub(super) fn error<S: Into<String>>(&mut self, msg: S, dsym: &DebugSymRef) {
Expand Down Expand Up @@ -360,7 +397,7 @@ mod test {

assert_eq!(
format!("{:?}", result),
r#"AnalysisResult { symbols: "/": ScopeTable { symbols: "\"fibo\": SymTableEntry { definition_ref: DebugSymRef { start: \"2:9\", end: \"40:13\" }, category: Machine, ty: None }", scope: Global },"//fibo": ScopeTable { symbols: "\"a\": SymTableEntry { definition_ref: DebugSymRef { line: 5, cols: \"13-32\" }, category: Signal, ty: Some(\"field\") },\"b\": SymTableEntry { definition_ref: DebugSymRef { line: 2, cols: \"33-48\" }, category: OutputSignal, ty: Some(\"field\") },\"final\": SymTableEntry { definition_ref: DebugSymRef { start: \"2:50\", end: \"40:13\" }, category: State, ty: None },\"i\": SymTableEntry { definition_ref: DebugSymRef { line: 5, cols: \"13-32\" }, category: Signal, ty: None },\"initial\": SymTableEntry { definition_ref: DebugSymRef { start: \"10:13\", end: \"18:14\" }, category: State, ty: None },\"middle\": SymTableEntry { definition_ref: DebugSymRef { start: \"20:13\", end: \"34:14\" }, category: State, ty: None },\"n\": SymTableEntry { definition_ref: DebugSymRef { line: 2, cols: \"22-30\" }, category: InputSignal, ty: None }", scope: Machine },"//fibo/final": ScopeTable { symbols: "", scope: State },"//fibo/initial": ScopeTable { symbols: "\"c\": SymTableEntry { definition_ref: DebugSymRef { line: 11, cols: \"14-23\" }, category: Signal, ty: None }", scope: State },"//fibo/middle": ScopeTable { symbols: "\"c\": SymTableEntry { definition_ref: DebugSymRef { line: 21, cols: \"14-23\" }, category: Signal, ty: None }", scope: State }, messages: [] }"#
r#"AnalysisResult { symbols: "/": ScopeTable { symbols: "\"fibo\": SymTableEntry { id: \"fibo\", definition_ref: DebugSymRef { start: \"2:9\", end: \"40:13\" }, usages: [], category: Machine, ty: None }", scope: Global },"//fibo": ScopeTable { symbols: "\"a\": SymTableEntry { id: \"a\", definition_ref: DebugSymRef { line: 5, cols: \"13-32\" }, usages: [DebugSymRef { line: 13, cols: \"17-18\" }, DebugSymRef { line: 16, cols: \"15-17\" }, DebugSymRef { line: 23, cols: \"20-21\" }, DebugSymRef { line: 31, cols: \"20-22\" }], category: Signal, ty: Some(\"field\") },\"b\": SymTableEntry { id: \"b\", definition_ref: DebugSymRef { line: 2, cols: \"33-48\" }, usages: [DebugSymRef { line: 13, cols: \"20-21\" }, DebugSymRef { line: 16, cols: \"30-31\" }, DebugSymRef { line: 16, cols: \"19-21\" }, DebugSymRef { line: 23, cols: \"24-25\" }, DebugSymRef { line: 27, cols: \"20-22\" }, DebugSymRef { line: 31, cols: \"42-43\" }, DebugSymRef { line: 31, cols: \"24-26\" }], category: OutputSignal, ty: Some(\"field\") },\"final\": SymTableEntry { id: \"final\", definition_ref: DebugSymRef { start: \"2:50\", end: \"40:13\" }, usages: [DebugSymRef { line: 26, cols: \"18-23\" }], category: State, ty: None },\"i\": SymTableEntry { id: \"i\", definition_ref: DebugSymRef { line: 5, cols: \"13-32\" }, usages: [DebugSymRef { line: 13, cols: \"14-15\" }, DebugSymRef { line: 25, cols: \"17-18\" }, DebugSymRef { line: 27, cols: \"31-32\" }, DebugSymRef { line: 27, cols: \"16-18\" }, DebugSymRef { line: 31, cols: \"35-36\" }, DebugSymRef { line: 31, cols: \"16-18\" }], category: Signal, ty: None },\"initial\": SymTableEntry { id: \"initial\", definition_ref: DebugSymRef { start: \"10:13\", end: \"18:14\" }, usages: [], category: State, ty: None },\"middle\": SymTableEntry { id: \"middle\", definition_ref: DebugSymRef { start: \"20:13\", end: \"34:14\" }, usages: [DebugSymRef { line: 15, cols: \"17-23\" }, DebugSymRef { line: 30, cols: \"18-24\" }], category: State, ty: None },\"n\": SymTableEntry { id: \"n\", definition_ref: DebugSymRef { line: 2, cols: \"22-30\" }, usages: [DebugSymRef { line: 16, cols: \"36-37\" }, DebugSymRef { line: 16, cols: \"23-25\" }, DebugSymRef { line: 25, cols: \"26-27\" }, DebugSymRef { line: 27, cols: \"41-42\" }, DebugSymRef { line: 27, cols: \"24-26\" }, DebugSymRef { line: 31, cols: \"48-49\" }, DebugSymRef { line: 31, cols: \"28-30\" }], category: InputSignal, ty: None }", scope: Machine },"//fibo/final": ScopeTable { symbols: "", scope: State },"//fibo/initial": ScopeTable { symbols: "\"c\": SymTableEntry { id: \"c\", definition_ref: DebugSymRef { line: 11, cols: \"14-23\" }, usages: [DebugSymRef { line: 13, cols: \"23-24\" }, DebugSymRef { line: 16, cols: \"33-34\" }], category: Signal, ty: None }", scope: State },"//fibo/middle": ScopeTable { symbols: "\"c\": SymTableEntry { id: \"c\", definition_ref: DebugSymRef { line: 21, cols: \"14-23\" }, usages: [DebugSymRef { line: 23, cols: \"14-15\" }, DebugSymRef { line: 27, cols: \"38-39\" }, DebugSymRef { line: 31, cols: \"45-46\" }], category: Signal, ty: None }", scope: State }, messages: [] }"#
)
}
}
Loading
Loading