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,
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() {
29 use crate::core::lexer::token::TokenKind;
30
31 if first_token.kind == TokenKind::Dot {
32 let dot_stmt = parse_dot_token(parser, _global_store);
34 match dot_stmt.kind {
36 StatementKind::Trigger { entity, .. } => entity,
37 _ => String::new(),
38 }
39 } else {
40 if first_token.kind != crate::core::lexer::token::TokenKind::Identifier
41 && first_token.kind != crate::core::lexer::token::TokenKind::Number
42 && first_token.kind != crate::core::lexer::token::TokenKind::Synth
43 {
44 return crate::core::parser::statement::error_from_token(
45 first_token.clone(),
46 "Expected identifier after 'synth'".to_string(),
47 );
48 }
49
50 let mut parts: Vec<String> = Vec::new();
52 let current_line = first_token.line;
53 loop {
54 let Some(tok) = parser.peek_clone() else {
55 break;
56 };
57 if tok.line != current_line {
58 break;
59 }
60 match tok.kind {
61 crate::core::lexer::token::TokenKind::Identifier
62 | crate::core::lexer::token::TokenKind::Number
63 | crate::core::lexer::token::TokenKind::Synth => {
64 parts.push(tok.lexeme.clone());
65 parser.advance();
66 if let Some(next) = parser.peek_clone() {
68 if !(next.line == current_line
69 && next.kind == crate::core::lexer::token::TokenKind::Dot)
70 {
71 break;
72 }
73 } else {
74 break;
75 }
76 }
77 crate::core::lexer::token::TokenKind::Dot => {
78 parser.advance();
79 }
80 _ => break,
81 }
82 }
83
84 parts.join(".")
85 }
86 } else {
87 return crate::core::parser::statement::error_from_token(
88 synth_token,
89 "Expected identifier after 'synth'".to_string(),
90 );
91 };
92
93 while parser.check_token(crate::core::lexer::token::TokenKind::Newline)
95 || parser.check_token(crate::core::lexer::token::TokenKind::Indent)
96 || parser.check_token(crate::core::lexer::token::TokenKind::Dedent)
97 || parser.check_token(crate::core::lexer::token::TokenKind::Whitespace)
98 {
99 parser.advance();
100 }
101
102 let parameters = if let Some(params) = parser.parse_map_value() {
104 if let Value::Map(map) = params {
106 map
107 } else {
108 return crate::core::parser::statement::error_from_token(
109 synth_token,
110 "Expected a map for synth parameters".to_string(),
111 );
112 }
113 } else {
114 HashMap::new()
116 };
117
118 Statement {
119 kind: StatementKind::Synth,
120 value: Value::Map(HashMap::from([
121 ("entity".to_string(), Value::String("synth".to_string())),
122 (
123 "value".to_string(),
124 Value::Map(HashMap::from([
125 ("waveform".to_string(), Value::Identifier(synth_waveform)),
127 ("parameters".to_string(), Value::Map(parameters)),
128 ])),
129 ),
130 ])),
131 indent: synth_token.indent,
132 line: synth_token.line,
133 column: synth_token.column,
134 }
135}