Compare commits

...

2 Commits

Author SHA1 Message Date
696bfc55f4 remove str
All checks were successful
Check / Explore-Gitea-Actions (push) Successful in 13s
2026-04-13 12:33:43 +02:00
c33c7f45a0 abbreviate binary ops 2026-04-13 10:42:49 +02:00
7 changed files with 31 additions and 56 deletions

View File

@ -174,7 +174,7 @@ export type IntTy =
export type UnaryOp = export type UnaryOp =
| "Not" | "Not"
| "Negate" | "Neg"
| "Ref" | "Ref"
| "RefMut" | "RefMut"
| "Deref"; | "Deref";
@ -194,10 +194,10 @@ export type BinaryOp =
| "Shl" | "Shl"
| "Shr" | "Shr"
| "Add" | "Add"
| "Subtract" | "Sub"
| "Multiply" | "Mul"
| "Divide" | "Div"
| "Remainder"; | "Rem";
export type RangeLimit = "Inclusive" | "Exclusive"; export type RangeLimit = "Inclusive" | "Exclusive";

View File

@ -205,7 +205,9 @@ class ExprChecker {
case "IntExpr": case "IntExpr":
return this.checkIntExpr(node.as(tag)); return this.checkIntExpr(node.as(tag));
case "StrExpr": case "StrExpr":
return Ty.create("Ptr", { ty: Ty.Str }); return Ty.create("Ptr", {
ty: Ty.create("Slice", { ty: Ty.U8 }),
});
case "ArrayExpr": case "ArrayExpr":
return this.checkArrayExpr(node.as(tag)); return this.checkArrayExpr(node.as(tag));
case "IndexExpr": case "IndexExpr":
@ -300,12 +302,6 @@ class ExprChecker {
) { ) {
return Ty.create("Slice", { ty: exprTy.kind.ty }); return Ty.create("Slice", { ty: exprTy.kind.ty });
} }
if (
exprTy.is("Str") &&
argTy.compatibleWith(Ty.I32)
) {
return Ty.I32;
}
this.cx.error( this.cx.error(
node.loc, node.loc,
`cannot use index operator on '${exprTy.pretty()}' with '${argTy.pretty()}'`, `cannot use index operator on '${exprTy.pretty()}' with '${argTy.pretty()}'`,
@ -386,8 +382,7 @@ class ExprChecker {
!(argTy.is("Array") || !(argTy.is("Array") ||
argTy.is("Ptr") && argTy.is("Ptr") &&
(argTy.kind.ty.is("Array") || (argTy.kind.ty.is("Array") ||
argTy.kind.ty.is("Slice") || argTy.kind.ty.is("Slice")))
argTy.kind.ty.is("Str")))
) { ) {
this.reportArgTypeNotCompatible( this.reportArgTypeNotCompatible(
node, node,
@ -409,7 +404,7 @@ class ExprChecker {
private checkUnaryExpr(node: ast.NodeWithKind<"UnaryExpr">): Ty { private checkUnaryExpr(node: ast.NodeWithKind<"UnaryExpr">): Ty {
const exprTy = this.cx.expr(node.kind.expr); const exprTy = this.cx.expr(node.kind.expr);
if (node.kind.op === "Negate" && exprTy.compatibleWith(Ty.I32)) { if (node.kind.op === "Neg" && exprTy.compatibleWith(Ty.I32)) {
return Ty.I32; return Ty.I32;
} }
if (node.kind.op === "Not" && exprTy.compatibleWith(Ty.Bool)) { if (node.kind.op === "Not" && exprTy.compatibleWith(Ty.Bool)) {
@ -530,8 +525,6 @@ class TyChecker {
return Ty.Void; return Ty.Void;
case "bool": case "bool":
return Ty.Bool; return Ty.Bool;
case "str":
return Ty.Str;
case "i8": case "i8":
return Ty.I8; return Ty.I8;
case "i16": case "i16":
@ -605,7 +598,13 @@ type BinaryOpTest = (op: ast.BinaryOp, left: Ty, right: Ty) => Ty | null;
const binaryOpTests: BinaryOpTest[] = [ const binaryOpTests: BinaryOpTest[] = [
(op, left, right) => { (op, left, right) => {
const ops = ["Add", "Subtract", "Multiply", "Divide", "Remainder"]; const ops: ast.BinaryOp[] = [
"Add",
"Sub",
"Mul",
"Div",
"Rem",
];
if ( if (
ops.includes(op) && left.is("Int") && left.compatibleWith(right) ops.includes(op) && left.is("Int") && left.compatibleWith(right)
) { ) {
@ -614,7 +613,7 @@ const binaryOpTests: BinaryOpTest[] = [
return null; return null;
}, },
(op, left, right) => { (op, left, right) => {
const ops = ["Eq", "Ne", "Lt", "Gt", "Lte", "Gte"]; const ops: ast.BinaryOp[] = ["Eq", "Ne", "Lt", "Gt", "Lte", "Gte"];
if ( if (
ops.includes(op) && left.is("Int") && left.compatibleWith(right) ops.includes(op) && left.is("Int") && left.compatibleWith(right)
) { ) {

View File

@ -197,10 +197,10 @@ export class Parser {
["<<", "Shl", 3], ["<<", "Shl", 3],
[">>", "Shr", 3], [">>", "Shr", 3],
["+", "Add", 2], ["+", "Add", 2],
["-", "Subtract", 2], ["-", "Sub", 2],
["*", "Multiply", 1], ["*", "Mul", 1],
["/", "Divide", 1], ["/", "Div", 1],
["%", "Remainder", 1], ["%", "Rem", 1],
]; ];
let left = this.parseBinary(prec - 1); let left = this.parseBinary(prec - 1);
@ -228,7 +228,7 @@ export class Parser {
const loc = this.loc(); const loc = this.loc();
const ops: [Tok["type"], ast.UnaryOp][] = [ const ops: [Tok["type"], ast.UnaryOp][] = [
["not", "Not"], ["not", "Not"],
["-", "Negate"], ["-", "Neg"],
["*", "Deref"], ["*", "Deref"],
]; ];
for (const [tok, op] of ops) { for (const [tok, op] of ops) {

View File

@ -248,17 +248,6 @@ class FnLowerer {
); );
} }
} }
if (valueTy.is("Str")) {
const valueInst = this.lowerPlace(place.kind.value);
if (argTy.is("Int")) {
const argInst = this.lowerExpr(arg);
return this.pushInst(
Ty.create("Ptr", { ty: Ty.I32 }),
"GetElemPtr",
{ base: valueInst, offset: argInst },
);
}
}
throw new Error( throw new Error(
`${place.kind.tag} with arg ${argTy.pretty()} not handled`, `${place.kind.tag} with arg ${argTy.pretty()} not handled`,
); );
@ -356,7 +345,7 @@ class FnLowerer {
const resultTy = this.tys.expr(expr); const resultTy = this.tys.expr(expr);
const operandTy = this.tys.expr(expr.kind.expr); const operandTy = this.tys.expr(expr.kind.expr);
if ( if (
expr.kind.op === "Negate" && expr.kind.op === "Neg" &&
operandTy.compatibleWith(Ty.I32) && operandTy.compatibleWith(Ty.I32) &&
resultTy.compatibleWith(Ty.I32) resultTy.compatibleWith(Ty.I32)
) { ) {
@ -435,21 +424,14 @@ type BinaryOpTest = (
const binaryOpTests: BinaryOpTest[] = [ const binaryOpTests: BinaryOpTest[] = [
(op, left, right, result) => { (op, left, right, result) => {
const ops = ["Add", "Subtract", "Multiply", "Divide", "Remainder"]; const ops: ast.BinaryOp[] = ["Add", "Sub", "Mul", "Div", "Rem"];
const tags: Record<string, BinaryOp> = {
"Add": "Add",
"Subtract": "Sub",
"Multiply": "Mul",
"Divide": "Div",
"Remainder": "Rem",
};
if ( if (
ops.includes(op) && ops.includes(op) &&
left.is("Int") && left.is("Int") &&
left.compatibleWith(right) && left.compatibleWith(right) &&
result.compatibleWith(left) result.compatibleWith(left)
) { ) {
return tags[op]; return op as BinaryOp;
} }
return null; return null;
}, },

View File

@ -199,12 +199,13 @@ export type InstKind =
| { tag: "Jump"; target: BasicBlock } | { tag: "Jump"; target: BasicBlock }
| { tag: "Branch"; cond: Inst; truthy: BasicBlock; falsy: BasicBlock } | { tag: "Branch"; cond: Inst; truthy: BasicBlock; falsy: BasicBlock }
| { tag: "Return"; source: Inst } | { tag: "Return"; source: Inst }
| { tag: "Not"; source: Inst } | { tag: UnaryOp; source: Inst }
| { tag: "Negate"; source: Inst }
| { tag: BinaryOp; left: Inst; right: Inst } | { tag: BinaryOp; left: Inst; right: Inst }
| { tag: "Len"; source: Inst } | { tag: "Len"; source: Inst }
| { tag: "DebugPrint"; args: Inst[] }; | { tag: "DebugPrint"; args: Inst[] };
export type UnaryOp = "Not" | "Negate";
export type BinaryOp = export type BinaryOp =
| "Eq" | "Eq"
| "Ne" | "Ne"

View File

@ -35,7 +35,6 @@ export class Ty {
static U64 = Ty.create("Int", { intTy: "u64" }); static U64 = Ty.create("Int", { intTy: "u64" });
static USize = Ty.create("Int", { intTy: "usize" }); static USize = Ty.create("Int", { intTy: "usize" });
static Bool = Ty.create("Bool", {}); static Bool = Ty.create("Bool", {});
static Str = Ty.create("Str", {});
private internHash(): string { private internHash(): string {
return JSON.stringify(this.kind); return JSON.stringify(this.kind);
@ -75,9 +74,6 @@ export class Ty {
if (this.is("Bool")) { if (this.is("Bool")) {
return other.is("Bool"); return other.is("Bool");
} }
if (this.is("Str")) {
return other.is("Str");
}
if (this.is("Ptr")) { if (this.is("Ptr")) {
if (!other.is("Ptr")) { if (!other.is("Ptr")) {
return false; return false;
@ -142,7 +138,7 @@ export class Ty {
} }
isSized(): boolean { isSized(): boolean {
if (this.is("Slice") || this.is("Str")) { if (this.is("Slice")) {
return false; return false;
} }
return true; return true;
@ -160,8 +156,6 @@ export class Ty {
return `${this.kind.intTy}`; return `${this.kind.intTy}`;
case "Bool": case "Bool":
return "bool"; return "bool";
case "Str":
return "str";
case "Ptr": case "Ptr":
return `*${this.kind.ty.pretty()}`; return `*${this.kind.ty.pretty()}`;
case "PtrMut": case "PtrMut":
@ -199,7 +193,6 @@ export type TyKind =
| { tag: "IntLiteral" } | { tag: "IntLiteral" }
| { tag: "Int"; intTy: ast.IntTy } | { tag: "Int"; intTy: ast.IntTy }
| { tag: "Bool" } | { tag: "Bool" }
| { tag: "Str" }
| { tag: "Ptr"; ty: Ty } | { tag: "Ptr"; ty: Ty }
| { tag: "PtrMut"; ty: Ty } | { tag: "PtrMut"; ty: Ty }
| { tag: "Array"; ty: Ty; length: number } | { tag: "Array"; ty: Ty; length: number }

View File

@ -1,7 +1,7 @@
fn main() fn main()
{ {
let my_string: *str = "hello world"; let my_string: *[u8] = "hello world";
// expect: hello world // expect: hello world
print(my_string); print(my_string);
// expect: 104 // expect: 104