diff --git a/README.md b/README.md index 6f9aea0..365a6aa 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,15 @@ English | [简体中文](./README.zh-CN.md) > This project is IEC-61131-3 Compiler implementation for technologies research. - +<p align="center"> +<img src="./screenshots/Screenshot_20231216_233926.png"><br> +LSP-based syntax highlighting +</p> + +<p align="center"> +<img src="./screenshots/Screenshot_20231209_230838.png"><br> +A compiler data viewer tools UI +</p> ### TODO-List - [ ] LSP implementation diff --git a/lib/src/parser/lexer.rs b/lib/src/parser/lexer.rs index b43195d..4094225 100644 --- a/lib/src/parser/lexer.rs +++ b/lib/src/parser/lexer.rs @@ -430,6 +430,7 @@ impl<'input> StLexer<'input> { return self.parse_floating(tok, s); } _ => { + tok.length = s.len(); tok.tok = Tok::Literal(LiteralValue::UInt(s.parse().unwrap())); return Some(Ok(tok)); } diff --git a/lib/src/parser/token.rs b/lib/src/parser/token.rs index b6df76f..20a9190 100644 --- a/lib/src/parser/token.rs +++ b/lib/src/parser/token.rs @@ -162,10 +162,12 @@ impl Tok { pub fn is_operator(&self) -> bool { matches!( self, - Tok::LessEqual - | Tok::Less + Tok::Less + | Tok::LessEqual + | Tok::Greater | Tok::GreaterEqual | Tok::Equal + | Tok::NotEqual | Tok::Plus | Tok::Minus | Tok::Division diff --git a/lsp/src/lsp.rs b/lsp/src/lsp.rs index 1def73e..802ec81 100644 --- a/lsp/src/lsp.rs +++ b/lsp/src/lsp.rs @@ -1,5 +1,5 @@ use serde_json::Value; -use stc::parser::StLexerBuilder; +use stc::parser::{StLexerBuilder, Tok}; use tower_lsp::jsonrpc; use tower_lsp::jsonrpc::Result; use tower_lsp::lsp_types::*; @@ -25,8 +25,11 @@ impl LanguageServer for StcLsp { }, legend: SemanticTokensLegend { token_types: vec![ + SemanticTokenType::KEYWORD, SemanticTokenType::VARIABLE, SemanticTokenType::NUMBER, + SemanticTokenType::STRING, + SemanticTokenType::OPERATOR, SemanticTokenType::FUNCTION, ], token_modifiers: vec![], @@ -92,11 +95,44 @@ impl LanguageServer for StcLsp { let lexer = StLexerBuilder::new() .build_file(params.text_document.uri.path()) .map_err(|_| jsonrpc::Error::invalid_request())?; - for tok in lexer { - info!("{:?}", tok.unwrap().tok); + + let mut last_line = 0; + let mut last_offset = 0; + let mut tokens: Vec<SemanticToken> = vec![]; + for tok in lexer.flatten() { + if tok.pos.line != last_line { + last_offset = 0; + } + + let tok_type = match tok.tok { + Tok::Identifier(_) => 1, + Tok::Literal(_) => 2, + Tok::String => 3, + op if op.is_operator() => 4, + _ => 0, + }; + + let token = SemanticToken { + delta_line: (tok.pos.line - last_line) as u32, + delta_start: (tok.pos.offset - last_offset) as u32, + length: tok.length as u32, + token_type: tok_type, + ..Default::default() + }; + tokens.push(token); + + last_line = tok.pos.line; + last_offset = tok.pos.offset; } - Ok(None) + for x in &tokens { + trace!("{:?}", x); + } + + Ok(Some(SemanticTokensResult::Tokens(SemanticTokens { + result_id: None, + data: tokens, + }))) } async fn semantic_tokens_full_delta( diff --git a/screenshots/Screenshot_20231216_233926.png b/screenshots/Screenshot_20231216_233926.png new file mode 100644 index 0000000..26fb3f7 Binary files /dev/null and b/screenshots/Screenshot_20231216_233926.png differ