Phase 5: Editor und inkrementellen Compiler implementieren und archivieren
This commit is contained in:
@@ -9,6 +9,8 @@ use crate::lexer::{Kw, NumValue, Token, TokenKind};
|
||||
use crate::{Diagnostic, SourcePos};
|
||||
|
||||
pub struct ParseOutput {
|
||||
/// Ausschließlich fehlende Blockabschlüsse am Dateiende.
|
||||
pub incomplete: bool,
|
||||
pub module: Module,
|
||||
pub diagnostics: Vec<Diagnostic>,
|
||||
}
|
||||
@@ -19,6 +21,7 @@ pub fn parse(module_name: &str, tokens: &[Token]) -> ParseOutput {
|
||||
i: 0,
|
||||
diags: Vec::new(),
|
||||
at_line_start: true,
|
||||
incomplete_errors: 0,
|
||||
};
|
||||
let mut body = Vec::new();
|
||||
let mut procs = Vec::new();
|
||||
@@ -56,6 +59,7 @@ pub fn parse(module_name: &str, tokens: &[Token]) -> ParseOutput {
|
||||
}
|
||||
|
||||
ParseOutput {
|
||||
incomplete: !p.diags.is_empty() && p.incomplete_errors == p.diags.len(),
|
||||
module: Module {
|
||||
name: module_name.to_string(),
|
||||
body,
|
||||
@@ -70,6 +74,7 @@ struct P<'a> {
|
||||
i: usize,
|
||||
diags: Vec<Diagnostic>,
|
||||
at_line_start: bool,
|
||||
incomplete_errors: usize,
|
||||
}
|
||||
|
||||
impl<'a> P<'a> {
|
||||
@@ -105,10 +110,27 @@ impl<'a> P<'a> {
|
||||
}
|
||||
fn err(&mut self, msg: impl Into<String>) {
|
||||
let pos = self.pos();
|
||||
let msg = msg.into();
|
||||
if matches!(self.k(), TokenKind::Eof)
|
||||
&& matches!(
|
||||
msg.as_str(),
|
||||
"Expected: END SUB"
|
||||
| "Expected: END FUNCTION"
|
||||
| "Expected: END IF"
|
||||
| "Expected: END SELECT"
|
||||
| "Expected: END TYPE"
|
||||
| "Expected: END DEF"
|
||||
| "Expected: NEXT"
|
||||
| "Expected: LOOP"
|
||||
| "Expected: WEND"
|
||||
)
|
||||
{
|
||||
self.incomplete_errors += 1;
|
||||
}
|
||||
self.diags.push(Diagnostic {
|
||||
file: None,
|
||||
pos,
|
||||
message: msg.into(),
|
||||
message: msg,
|
||||
});
|
||||
}
|
||||
fn expect_kw(&mut self, kw: Kw, what: &str) -> bool {
|
||||
@@ -1783,6 +1805,7 @@ impl<'a> P<'a> {
|
||||
ProcKind::Function => Kw::Function,
|
||||
};
|
||||
let body = self.parse_stmt_list(|p: &P| p.at_end_pair(end_kw));
|
||||
let end_pos = self.pos();
|
||||
if self.at_end_pair(end_kw) {
|
||||
self.advance();
|
||||
self.advance();
|
||||
@@ -1797,6 +1820,7 @@ impl<'a> P<'a> {
|
||||
is_static,
|
||||
body,
|
||||
pos,
|
||||
end_pos,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user