feat(selfhost): add &T (shared ref) and &mut T (mutable ref) type syntax

- Add tekRef and tekMutRef to TypeExpr enum (ast.bux)
- Parse &T and &mut T in parserParseType, before *T handling (parser.bux)
- Map tekRef/tekMutRef to tyPointer in HIR lowering (hir_lower.bux)
- Both emit as T* in C backend (same as raw pointer)
- Borrow checker rejects write-through-pointer in @[Checked] functions
  for all pointer types (safe default)
This commit is contained in:
2026-06-09 17:30:19 +03:00
parent 81281cbb11
commit f809827bea
3 changed files with 30 additions and 1 deletions
+2
View File
@@ -26,6 +26,8 @@ const tekNamed: int = 0;
const tekPath: int = 1; const tekPath: int = 1;
const tekSlice: int = 2; const tekSlice: int = 2;
const tekPointer: int = 3; const tekPointer: int = 3;
const tekRef: int = 7; // &T — shared reference
const tekMutRef: int = 8; // &mut T — mutable reference
const tekTuple: int = 4; const tekTuple: int = 4;
const tekSelf: int = 5; const tekSelf: int = 5;
const tekFunc: int = 6; const tekFunc: int = 6;
+1 -1
View File
@@ -53,7 +53,7 @@ func Lcx_ResolveTypeKindFromName(name: String) -> int {
func Lcx_ResolveTypeKind(te: *TypeExpr) -> int { func Lcx_ResolveTypeKind(te: *TypeExpr) -> int {
if te == null as *TypeExpr { return tyUnknown; } if te == null as *TypeExpr { return tyUnknown; }
if te.kind == tekPointer { return tyPointer; } if te.kind == tekPointer || te.kind == tekRef || te.kind == tekMutRef { return tyPointer; }
if te.kind == tekSlice { return tySlice; } if te.kind == tekSlice { return tySlice; }
if te.kind == tekTuple { return tyTuple; } if te.kind == tekTuple { return tyTuple; }
if te.kind == tekFunc { return tyFunc; } if te.kind == tekFunc { return tyFunc; }
+27
View File
@@ -149,6 +149,33 @@ func parserParseType(p: *Parser) -> *TypeExpr {
let col: uint32 = parserCurToken(p).column; let col: uint32 = parserCurToken(p).column;
let kindTok: int = parserPeek(p, 0); let kindTok: int = parserPeek(p, 0);
// &T (shared reference) and &mut T (mutable reference)
if kindTok == tkAmp {
discard parserAdvance(p); // &
var isMut: bool = false;
// Check for "mut" keyword
if parserCheck(p, tkIdent) {
let tok: LexToken = parserCurToken(p);
if String_Eq(tok.text, "mut") {
isMut = true;
discard parserAdvance(p); // mut
}
}
let te: *TypeExpr = bux_alloc(sizeof(TypeExpr)) as *TypeExpr;
if isMut {
te.kind = tekMutRef;
} else {
te.kind = tekRef;
}
te.line = line;
te.column = col;
te.pointerPointee = parserParseType(p);
if te.pointerPointee != null as *TypeExpr {
te.typeName = String_Concat(te.pointerPointee.typeName, "*");
}
return te;
}
// *T (pointer) // *T (pointer)
if kindTok == tkStar { if kindTok == tkStar {
discard parserAdvance(p); discard parserAdvance(p);