mimium_language_server/
semantic_token.rs1use std::{collections::VecDeque, path::PathBuf};
2
3use mimium_lang::{
4 ast::{program::Program, statement::Statement},
5 interner::ExprNodeId,
6 pattern::TypedId,
7 utils::{error::ReportableError, metadata::Span},
8};
9use tower_lsp::lsp_types::{SemanticTokenType, SemanticTokens};
10
11#[derive(Debug)]
13pub struct ImCompleteSemanticToken {
14 pub start: usize,
15 pub length: usize,
16 pub token_type: usize,
17}
18
19pub const LEGEND_TYPE: &[SemanticTokenType] = &[
20 SemanticTokenType::FUNCTION,
21 SemanticTokenType::VARIABLE,
22 SemanticTokenType::STRING,
23 SemanticTokenType::COMMENT,
24 SemanticTokenType::NUMBER,
25 SemanticTokenType::KEYWORD,
26 SemanticTokenType::OPERATOR,
27 SemanticTokenType::PARAMETER,
28 SemanticTokenType::PROPERTY,
29 SemanticTokenType::MACRO,
30 SemanticTokenType::TYPE,
31 SemanticTokenType::TYPE_PARAMETER,
32];
33pub struct ParseResult {
34 pub ast: ExprNodeId,
35 pub semantic_tokens: Vec<ImCompleteSemanticToken>,
36 pub errors: Vec<Box<dyn ReportableError>>,
37}
38use mimium_lang::compiler::parser::Token;
39
40fn get_token_id(semt: &SemanticTokenType) -> usize {
41 LEGEND_TYPE.iter().position(|item| item == semt).unwrap()
42}
43fn token_to_semantic_token(token: &Token, span: &Span) -> Option<ImCompleteSemanticToken> {
44 let token_type = match token {
45 Token::Function
46 | Token::Let
47 | Token::LetRec
48 | Token::If
49 | Token::Else
50 | Token::SelfLit
51 | Token::Now
52 | Token::SampleRate => get_token_id(&SemanticTokenType::KEYWORD),
53 Token::Ident(_) => get_token_id(&SemanticTokenType::VARIABLE),
54 Token::Float(_) | Token::Int(_) => get_token_id(&SemanticTokenType::NUMBER),
55 Token::Str(_) => get_token_id(&SemanticTokenType::STRING),
56 Token::Comment(_) => get_token_id(&SemanticTokenType::COMMENT),
57 Token::Assign | Token::Dollar | Token::BackQuote | Token::Op(_) => {
58 get_token_id(&SemanticTokenType::OPERATOR)
59 }
60 Token::StringType | Token::IntegerType | Token::FloatType | Token::StructType => {
61 get_token_id(&SemanticTokenType::TYPE)
62 }
63 Token::MacroExpand(_) => get_token_id(&SemanticTokenType::MACRO),
64
65 _ => return None,
66 };
67 Some(ImCompleteSemanticToken {
68 start: span.start,
69 length: span.end - span.start,
70 token_type,
71 })
72}
73
74pub fn parse(src: &str, uri: &str) -> ParseResult {
75 let (tokens, mut errs) = mimium_lang::compiler::parser::lex(src, Some(PathBuf::from(uri)));
76 let semantic_token = if let Some(tks) = tokens {
77 tks.iter()
78 .filter_map(|(token, span)| token_to_semantic_token(token, &(span.start..span.end)))
79 .collect()
80 } else {
81 Vec::new()
82 };
83 let (ast, parse_errs) =
84 mimium_lang::compiler::parser::parse_to_expr(src, Some(PathBuf::from(uri)));
85 errs.extend(parse_errs);
86 ParseResult {
87 ast,
88 semantic_tokens: semantic_token,
89 errors: errs,
90 }
91}