Disammbler und Simulator angepasst. Arrays begonnen (defunct)
This commit is contained in:
@ -14,6 +14,7 @@ public class StParser {
|
||||
StLexer lex;
|
||||
Token cur;
|
||||
Dictionary<string,Symbol> syms = new();
|
||||
public Dictionary<string,ArrayType> arrayTypes = new(); // Add dictionary for array types
|
||||
public List<CompileError> Errors => lex.Errors;
|
||||
public bool HasErrors => Errors.Count > 0;
|
||||
|
||||
@ -61,42 +62,96 @@ public class StParser {
|
||||
return p;
|
||||
}
|
||||
|
||||
VarType? ParseType(string varName) {
|
||||
if (cur.Type == TokType.ARRAY) {
|
||||
Next(); // Skip ARRAY
|
||||
if (!Expect(TokType.LBRACKET)) return null;
|
||||
var start = ParseExpr();
|
||||
if (start == null || start is not IntExpr startInt) {
|
||||
AddError("Array start index must be an integer constant");
|
||||
return null;
|
||||
}
|
||||
if (!Expect(TokType.DOTS)) return null;
|
||||
var end = ParseExpr();
|
||||
if (end == null || end is not IntExpr endInt) {
|
||||
AddError("Array end index must be an integer constant");
|
||||
return null;
|
||||
}
|
||||
if (!Expect(TokType.RBRACKET)) return null;
|
||||
if (!Expect(TokType.OF)) return null;
|
||||
if (cur.Type != TokType.IDENT) {
|
||||
AddError("Expected element type name after OF");
|
||||
return null;
|
||||
}
|
||||
string elemTypeName = cur.Text.ToLowerInvariant();
|
||||
Next();
|
||||
|
||||
VarType? elementType = elemTypeName switch {
|
||||
"bool" => VarType.BOOL,
|
||||
"byte" => VarType.BYTE,
|
||||
"word" => VarType.WORD,
|
||||
"dword" => VarType.DWORD,
|
||||
"lword" => VarType.LWORD,
|
||||
"sint" => VarType.SINT,
|
||||
"int" => VarType.INT,
|
||||
"dint" => VarType.DINT,
|
||||
"lint" => VarType.LINT,
|
||||
"usint" => VarType.USINT,
|
||||
"uint" => VarType.UINT,
|
||||
"udint" => VarType.UDINT,
|
||||
"ulint" => VarType.ULINT,
|
||||
"real" => VarType.REAL,
|
||||
"lreal" => VarType.LREAL,
|
||||
_ => null
|
||||
};
|
||||
|
||||
if (elementType == null) {
|
||||
AddError($"Unknown element type '{elemTypeName}'");
|
||||
return null;
|
||||
}
|
||||
|
||||
arrayTypes[varName] = new ArrayType(elementType.Value, (int)startInt.Value, (int)endInt.Value);
|
||||
return VarType.ARRAY;
|
||||
}
|
||||
else if (cur.Type == TokType.IDENT) {
|
||||
string typeName = cur.Text.ToLowerInvariant();
|
||||
Next();
|
||||
|
||||
return typeName switch {
|
||||
"bool" => VarType.BOOL,
|
||||
"byte" => VarType.BYTE,
|
||||
"word" => VarType.WORD,
|
||||
"dword" => VarType.DWORD,
|
||||
"lword" => VarType.LWORD,
|
||||
"sint" => VarType.SINT,
|
||||
"int" => VarType.INT,
|
||||
"dint" => VarType.DINT,
|
||||
"lint" => VarType.LINT,
|
||||
"usint" => VarType.USINT,
|
||||
"uint" => VarType.UINT,
|
||||
"udint" => VarType.UDINT,
|
||||
"ulint" => VarType.ULINT,
|
||||
"real" => VarType.REAL,
|
||||
"lreal" => VarType.LREAL,
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
AddError("Expected type name or ARRAY");
|
||||
return null;
|
||||
}
|
||||
|
||||
VarDecl? ParseVarDecl(){
|
||||
if (cur.Type != TokType.IDENT) {
|
||||
AddError("Expected identifier for variable declaration");
|
||||
return null;
|
||||
}
|
||||
string name=cur.Text.ToUpperInvariant(); // Variablennamen in Großbuchstaben
|
||||
string name = cur.Text.ToUpperInvariant(); // Variablennamen in Großbuchstaben
|
||||
Next();
|
||||
|
||||
if (cur.Type != TokType.IDENT) {
|
||||
AddError("Expected type name");
|
||||
return null;
|
||||
}
|
||||
string tname=cur.Text.ToLowerInvariant();
|
||||
Next();
|
||||
|
||||
VarType? vt = tname switch {
|
||||
"bool" => VarType.BOOL,
|
||||
"byte" => VarType.BYTE,
|
||||
"word" => VarType.WORD,
|
||||
"dword" => VarType.DWORD,
|
||||
"lword" => VarType.LWORD,
|
||||
"sint" => VarType.SINT,
|
||||
"int" => VarType.INT,
|
||||
"dint" => VarType.DINT,
|
||||
"lint" => VarType.LINT,
|
||||
"usint" => VarType.USINT,
|
||||
"uint" => VarType.UINT,
|
||||
"udint" => VarType.UDINT,
|
||||
"ulint" => VarType.ULINT,
|
||||
"real" => VarType.REAL,
|
||||
"lreal" => VarType.LREAL,
|
||||
_ => null
|
||||
};
|
||||
|
||||
var vt = ParseType(name);
|
||||
if (vt == null) {
|
||||
AddError($"Unknown type '{tname}'");
|
||||
AddError($"Invalid type for variable '{name}'");
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -121,6 +176,26 @@ public class StParser {
|
||||
Stmt? ParseAssign() {
|
||||
string target = cur.Text.ToUpperInvariant();
|
||||
Next(); // consume identifier
|
||||
|
||||
// Check if this is an array assignment
|
||||
Expr? index = null;
|
||||
if (cur.Type == TokType.LBRACKET) {
|
||||
Symbol? sym;
|
||||
if (!syms.TryGetValue(target, out sym)) {
|
||||
AddError($"Undeclared variable '{target}'");
|
||||
return null;
|
||||
}
|
||||
if (sym.Type != VarType.ARRAY) {
|
||||
AddError($"Cannot use array indexing on non-array variable '{target}'");
|
||||
return null;
|
||||
}
|
||||
|
||||
Next(); // consume [
|
||||
index = ParseExpr();
|
||||
if (index == null) return null;
|
||||
if (!Expect(TokType.RBRACKET)) return null;
|
||||
}
|
||||
|
||||
if (cur.Type != TokType.ASSIGN) {
|
||||
AddError($"Expected ':=' after identifier '{target}'");
|
||||
return null;
|
||||
@ -129,7 +204,7 @@ public class StParser {
|
||||
var e = ParseExpr();
|
||||
if (e == null) return null;
|
||||
if (!Expect(TokType.SEMI)) return null;
|
||||
return new AssignStmt{Target=target, Expr=e};
|
||||
return new AssignStmt{Target=target, Index=index, Expr=e};
|
||||
}
|
||||
|
||||
Stmt? ParseStmt(){
|
||||
@ -318,6 +393,29 @@ public class StParser {
|
||||
AddError($"Undeclared variable '{n}'");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check for array access
|
||||
if (cur.Type == TokType.LBRACKET) {
|
||||
if (sym.Type != VarType.ARRAY) {
|
||||
AddError($"Cannot index non-array variable '{n}'");
|
||||
return null;
|
||||
}
|
||||
|
||||
Next(); // consume [
|
||||
var idx = ParseExpr();
|
||||
if (idx == null) return null;
|
||||
|
||||
if (!Expect(TokType.RBRACKET)) return null;
|
||||
|
||||
ArrayType? arrayType;
|
||||
if (!arrayTypes.TryGetValue(n, out arrayType)) {
|
||||
AddError($"Internal error: Array type information missing for '{n}'");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ArrayAccessExpr(n, idx, arrayType.ElementType);
|
||||
}
|
||||
|
||||
return new VarExpr(n, sym.Type);
|
||||
|
||||
case TokType.LPAREN:
|
||||
@ -332,4 +430,9 @@ public class StParser {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayType? GetArrayType(string name) {
|
||||
ArrayType? type;
|
||||
return arrayTypes.TryGetValue(name, out type) ? type : null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user