Phase 1 vollstaendig abgeschlossen; neue Vorgaben verankert
Frontend-Vervollstaendigung (keine offenen Punkte mehr in Phase 1):
- MID$-Anweisung, DEF-FN-Blockform, COMMON/SHARED/STATIC,
LPRINT, VIEW PRINT, NAME AS, LOCK/UNLOCK, Ereignissteuerung
(TIMER/KEY(n)/UEVENT ON|OFF|STOP), Metabefehle $INCLUDE/$STATIC/$DYNAMIC
- Komplette Datei-E/A-Grammatik: OPEN (beide Syntaxen, inkl. ISAM- und
ACCESS/LOCK-Klauseln), CLOSE, FIELD, GET/PUT, LSET/RSET, WRITE, SEEK
- Semantik: UDT-Feldtypen, SHARED-Import von Modulvariablen,
Konstantenfaltung (Invalid constant), OPTION BASE erfasst
- Non-Features konsistent zur Compile-Zeit abgewiesen: Hardware-Naehe,
CHAIN, Grafik-Anweisungen, SOUND/PLAY ("Feature unavailable")
- 33 Frontend-Tests, Korpus-Meilenstein weiter gruen
Neue Vorgaben:
- Stufe-2-Ideen: SQLite/Embedded-SQL mit Record-Buffern; Runtime-
Bibliotheken (z.B. crossterm) als BASIC-Bibliotheken
- Erster Kompatibilitaetstest: github.com/cout/vbdos (extern, wird nicht
einvendort); binaer-.FRM-Konverter als Phase-4-Aufgabe (tbc convert-frm)
- Doku als Definition of Done: docs/ = Ist-Dokumentation, IDE-Hilfe
rendert Markdown dynamisch zur Fenstergroesse (Phase-5-Aufgabe)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -96,7 +96,7 @@ pub struct CaseArm {
|
||||
pub struct VarDecl {
|
||||
pub name: String,
|
||||
pub suffix: Option<Suffix>,
|
||||
/// `None` = Skalar; sonst Dimensionen `(untergrenze TO obergrenze)`.
|
||||
/// `None` = Skalar; leerer Vec = Array ohne Dimensionsangabe (`a()`).
|
||||
pub dims: Option<Vec<(Option<Expr>, Expr)>>,
|
||||
pub as_type: Option<TypeName>,
|
||||
pub pos: SourcePos,
|
||||
@@ -161,12 +161,47 @@ pub struct Proc {
|
||||
pub pos: SourcePos,
|
||||
}
|
||||
|
||||
/// `OPEN … FOR modus`.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum OpenMode {
|
||||
Input,
|
||||
Output,
|
||||
Append,
|
||||
Random,
|
||||
Binary,
|
||||
Isam,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum AccessMode {
|
||||
Read,
|
||||
Write,
|
||||
ReadWrite,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum LockClause {
|
||||
Shared,
|
||||
LockRead,
|
||||
LockWrite,
|
||||
LockReadWrite,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum EventAction {
|
||||
On,
|
||||
Off,
|
||||
Stop,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Stmt {
|
||||
Label(String),
|
||||
LineNumber(u32),
|
||||
Assign { target: Expr, value: Expr, pos: SourcePos },
|
||||
Print {
|
||||
/// LPRINT (Druckerausgabe) statt PRINT.
|
||||
printer: bool,
|
||||
file: Option<Expr>,
|
||||
using: Option<Expr>,
|
||||
items: Vec<PrintItem>,
|
||||
@@ -212,6 +247,17 @@ pub enum Stmt {
|
||||
System,
|
||||
Exit { kind: ExitKind, pos: SourcePos },
|
||||
Dim { shared: bool, redim: bool, decls: Vec<VarDecl>, pos: SourcePos },
|
||||
/// `SHARED`-Anweisung in einer Prozedur (Zugriff auf Modulvariablen).
|
||||
SharedDecl { decls: Vec<VarDecl>, pos: SourcePos },
|
||||
/// `STATIC`-Anweisung in einer Prozedur.
|
||||
StaticDecl { decls: Vec<VarDecl>, pos: SourcePos },
|
||||
/// `COMMON [SHARED] [/block/] liste`.
|
||||
CommonDecl {
|
||||
shared: bool,
|
||||
block: Option<String>,
|
||||
decls: Vec<VarDecl>,
|
||||
pos: SourcePos,
|
||||
},
|
||||
Erase { names: Vec<Expr>, pos: SourcePos },
|
||||
ConstDecl { items: Vec<(String, Option<Suffix>, Expr)>, pos: SourcePos },
|
||||
DefType { ty: TypeName, ranges: Vec<(char, char)>, pos: SourcePos },
|
||||
@@ -234,9 +280,69 @@ pub enum Stmt {
|
||||
body: Expr,
|
||||
pos: SourcePos,
|
||||
},
|
||||
/// Geparst, aber erst in Phase 3 implementiert (Datei-E/A u. ä.);
|
||||
/// die Tokens der Anweisung wurden übersprungen.
|
||||
NotYetImplemented { keyword: String, pos: SourcePos },
|
||||
/// Blockform `DEF FNname(...) … END DEF`.
|
||||
DefFnBlock {
|
||||
name: String,
|
||||
suffix: Option<Suffix>,
|
||||
params: Vec<Param>,
|
||||
body: Vec<Stmt>,
|
||||
pos: SourcePos,
|
||||
},
|
||||
// ---- Datei-E/A (Laufzeit in Phase 3, Grammatik vollständig) ----
|
||||
Open {
|
||||
file: Expr,
|
||||
mode: Option<OpenMode>,
|
||||
/// Bei `FOR ISAM typname tabellenname`.
|
||||
isam: Option<(String, String)>,
|
||||
access: Option<AccessMode>,
|
||||
lock: Option<LockClause>,
|
||||
number: Expr,
|
||||
len: Option<Expr>,
|
||||
pos: SourcePos,
|
||||
},
|
||||
/// Alte Syntax `OPEN modus$, [#]n, datei$ [, reclen]`.
|
||||
OpenLegacy {
|
||||
mode: Expr,
|
||||
number: Expr,
|
||||
file: Expr,
|
||||
len: Option<Expr>,
|
||||
pos: SourcePos,
|
||||
},
|
||||
CloseStmt { files: Vec<Expr>, pos: SourcePos },
|
||||
FieldStmt { file: Expr, fields: Vec<(Expr, Expr)>, pos: SourcePos },
|
||||
GetPut {
|
||||
put: bool,
|
||||
file: Expr,
|
||||
recnum: Option<Expr>,
|
||||
var: Option<Expr>,
|
||||
pos: SourcePos,
|
||||
},
|
||||
LsetRset { rset: bool, target: Expr, value: Expr, pos: SourcePos },
|
||||
WriteStmt { file: Option<Expr>, items: Vec<Expr>, pos: SourcePos },
|
||||
SeekStmt { file: Expr, position: Expr, pos: SourcePos },
|
||||
LockStmt {
|
||||
unlock: bool,
|
||||
file: Expr,
|
||||
from: Option<Expr>,
|
||||
to: Option<Expr>,
|
||||
pos: SourcePos,
|
||||
},
|
||||
NameStmt { old: Expr, new: Expr, pos: SourcePos },
|
||||
// ---- Bildschirm/Ereignisse ----
|
||||
/// `VIEW PRINT [oben TO unten]`.
|
||||
ViewPrint { top: Option<Expr>, bottom: Option<Expr>, pos: SourcePos },
|
||||
/// `TIMER ON`, `KEY(5) OFF`, `UEVENT STOP` …
|
||||
EventControl {
|
||||
device: String,
|
||||
index: Option<Expr>,
|
||||
action: EventAction,
|
||||
pos: SourcePos,
|
||||
},
|
||||
// ---- Metabefehle ----
|
||||
/// `'$INCLUDE: 'datei''` — Auflösung übernimmt der Compile-Treiber.
|
||||
Include { path: String, pos: SourcePos },
|
||||
/// `'$STATIC` / `'$DYNAMIC`.
|
||||
MetaArrays { static_arrays: bool, pos: SourcePos },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
|
||||
Reference in New Issue
Block a user