feat: backtick raw/multi-line strings + QBE backend fixes
- Add backtick raw string literals (Go-style ): no escape processing, multi-line - C backend: handle backtick strings in emitExpr - Self-hosted lexer: lexScanBacktickString support - QBE backend: handle backtick strings in data sections - QBE: remove broken extern declarations (QBE resolves at link time) - QBE: fix comparison result types (ceql → w, extend to l) - QBE: fix SSA parameter name clash (_p_ prefix for params) - QBE: const inlining via HirLower + QBE emitter - QBE: proper type mapping for bool/char types - hir_lower: collect dkConst declarations for const propagation
This commit is contained in:
+39
-12
@@ -78,10 +78,12 @@ func parserExpect(p: *Parser, kind: int, msg: String) -> LexToken {
|
||||
return parserAdvance(p);
|
||||
}
|
||||
let tok: LexToken = parserCurToken(p);
|
||||
p.diags[p.diagCount] = ParserDiag {
|
||||
line: tok.line, column: tok.column, message: msg
|
||||
};
|
||||
p.diagCount = p.diagCount + 1;
|
||||
if p.diagCount < 256 {
|
||||
p.diags[p.diagCount] = ParserDiag {
|
||||
line: tok.line, column: tok.column, message: msg
|
||||
};
|
||||
p.diagCount = p.diagCount + 1;
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
|
||||
@@ -103,10 +105,12 @@ func parserExpectIdentOrKeyword(p: *Parser, msg: String) -> LexToken {
|
||||
if tok.kind == tkIdent || parserIsKeyword(tok.kind) {
|
||||
return parserAdvance(p);
|
||||
}
|
||||
p.diags[p.diagCount] = ParserDiag {
|
||||
line: tok.line, column: tok.column, message: msg
|
||||
};
|
||||
p.diagCount = p.diagCount + 1;
|
||||
if p.diagCount < 256 {
|
||||
p.diags[p.diagCount] = ParserDiag {
|
||||
line: tok.line, column: tok.column, message: msg
|
||||
};
|
||||
p.diagCount = p.diagCount + 1;
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
|
||||
@@ -479,14 +483,33 @@ func parserIsBinaryOp(kind: int) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
func parserParseBinary(p: *Parser) -> *Expr {
|
||||
var left: *Expr = parserParsePostfix(p);
|
||||
func parserPrecedence(op: int) -> int {
|
||||
if op == tkAssign || op == tkPlusAssign || op == tkMinusAssign || op == tkStarAssign || op == tkSlashAssign || op == tkPercentAssign || op == tkAmpAssign || op == tkPipeAssign || op == tkCaretAssign || op == tkShlAssign || op == tkShrAssign { return 1; }
|
||||
if op == tkPipePipe { return 2; }
|
||||
if op == tkAmpAmp { return 3; }
|
||||
if op == tkPipe { return 4; }
|
||||
if op == tkCaret { return 5; }
|
||||
if op == tkAmp { return 6; }
|
||||
if op == tkEq || op == tkNe { return 7; }
|
||||
if op == tkLt || op == tkLe || op == tkGt || op == tkGe { return 8; }
|
||||
if op == tkShl || op == tkShr { return 9; }
|
||||
if op == tkPlus || op == tkMinus { return 10; }
|
||||
if op == tkStar || op == tkSlash || op == tkPercent { return 11; }
|
||||
if op == tkStarStar { return 12; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
while parserIsBinaryOp(parserPeek(p, 0)) {
|
||||
func parserParseBinaryPrec(p: *Parser, minPrec: int) -> *Expr {
|
||||
var left: *Expr = parserParsePostfix(p);
|
||||
while true {
|
||||
let op: int = parserPeek(p, 0);
|
||||
let prec: int = parserPrecedence(op);
|
||||
if prec < minPrec { break; }
|
||||
let opTok: LexToken = parserAdvance(p);
|
||||
let line: uint32 = opTok.line;
|
||||
let col: uint32 = opTok.column;
|
||||
let right: *Expr = parserParsePostfix(p);
|
||||
let nextMinPrec: int = prec + 1;
|
||||
let right: *Expr = parserParseBinaryPrec(p, nextMinPrec);
|
||||
let e: *Expr = parserMakeExpr(ekBinary, line, col);
|
||||
e.intValue = opTok.kind;
|
||||
e.child1 = left;
|
||||
@@ -496,6 +519,10 @@ func parserParseBinary(p: *Parser) -> *Expr {
|
||||
return left;
|
||||
}
|
||||
|
||||
func parserParseBinary(p: *Parser) -> *Expr {
|
||||
return parserParseBinaryPrec(p, 1);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Ternary: cond ? then : else
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user