devalang_core/core/parser/handler/identifier/
synth.rs1use std::collections::HashMap;
2
3use devalang_types::Value;
4
5use crate::core::{
6 lexer::token::Token,
7 parser::{
8 driver::parser::Parser,
9 handler::dot::parse_dot_token,
10 statement::{Statement, StatementKind},
11 },
12 store::global::GlobalStore,
13};
14
15pub fn parse_synth_token(
16 parser: &mut Parser,
17 _current_token: Token,
18 _global_store: &mut GlobalStore,
19) -> Statement {
20 parser.advance(); let Some(synth_token) = parser.previous_clone() else {
23 return Statement::unknown();
24 };
25
26 let synth_waveform = if let Some(first_token) = parser.peek_clone() {
30 use crate::core::lexer::token::TokenKind;
31
32 if first_token.kind == TokenKind::Dot {
33 let dot_stmt = parse_dot_token(parser, _global_store);
35 match dot_stmt.kind {
37 StatementKind::Trigger { entity, .. } => entity,
38 _ => String::new(),
39 }
40 } else {
41 if first_token.kind != crate::core::lexer::token::TokenKind::Identifier
42 && first_token.kind != crate::core::lexer::token::TokenKind::Number
43 && first_token.kind != crate::core::lexer::token::TokenKind::Synth
44 {
45 return crate::core::parser::statement::error_from_token(
46 first_token.clone(),
47 "Expected identifier after 'synth'".to_string(),
48 );
49 }
50
51 let mut parts: Vec<String> = Vec::new();
53 let current_line = first_token.line;
54 loop {
55 let Some(tok) = parser.peek_clone() else {
56 break;
57 };
58 if tok.line != current_line {
59 break;
60 }
61 match tok.kind {
62 crate::core::lexer::token::TokenKind::Identifier
63 | crate::core::lexer::token::TokenKind::Number
64 | crate::core::lexer::token::TokenKind::Synth => {
65 parts.push(tok.lexeme.clone());
66 parser.advance();
67 if let Some(next) = parser.peek_clone() {
69 if !(next.line == current_line
70 && next.kind == crate::core::lexer::token::TokenKind::Dot)
71 {
72 break;
73 }
74 } else {
75 break;
76 }
77 }
78 crate::core::lexer::token::TokenKind::Dot => {
79 parser.advance();
80 }
81 _ => break,
82 }
83 }
84
85 let first = parts.join(".");
89
90 if first.contains('.') {
95 if let Some(next_tok) = parser.peek_clone() {
97 if next_tok.line == current_line
98 && matches!(
99 next_tok.kind,
100 crate::core::lexer::token::TokenKind::Identifier
101 | crate::core::lexer::token::TokenKind::Number
102 | crate::core::lexer::token::TokenKind::Synth
103 )
104 {
105 let waveform = next_tok.lexeme.clone();
107 parser.advance();
108 waveform
110 } else {
111 first
113 }
114 } else {
115 first
116 }
117 } else {
118 first
120 }
121 }
122 } else {
123 return crate::core::parser::statement::error_from_token(
124 synth_token,
125 "Expected identifier after 'synth'".to_string(),
126 );
127 };
128
129 while parser.check_token(crate::core::lexer::token::TokenKind::Newline)
131 || parser.check_token(crate::core::lexer::token::TokenKind::Indent)
132 || parser.check_token(crate::core::lexer::token::TokenKind::Dedent)
133 || parser.check_token(crate::core::lexer::token::TokenKind::Whitespace)
134 {
135 parser.advance();
136 }
137
138 let parameters = if let Some(params) = parser.parse_map_value() {
140 if let Value::Map(map) = params {
142 map
143 } else {
144 return crate::core::parser::statement::error_from_token(
145 synth_token,
146 "Expected a map for synth parameters".to_string(),
147 );
148 }
149 } else {
150 HashMap::new()
152 };
153
154 Statement {
155 kind: StatementKind::Synth,
156 value: Value::Map(HashMap::from([
157 ("entity".to_string(), Value::String("synth".to_string())),
158 (
159 "value".to_string(),
160 Value::Map(HashMap::from([
161 ("waveform".to_string(), Value::Identifier(synth_waveform)),
163 ("parameters".to_string(), Value::Map(parameters)),
164 ])),
165 ),
166 ])),
167 indent: synth_token.indent,
168 line: synth_token.line,
169 column: synth_token.column,
170 }
171}