This commit is contained in:
parent
9d03272db8
commit
a42917b485
@ -1,23 +0,0 @@
|
|||||||
import { Ty } from "../ty.ts";
|
|
||||||
|
|
||||||
export type Builtin = {
|
|
||||||
id: string;
|
|
||||||
ty: Ty;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const builtins: Builtin[] = [
|
|
||||||
{
|
|
||||||
id: "print_int",
|
|
||||||
ty: Ty.create("Fn", {
|
|
||||||
params: [Ty.Int],
|
|
||||||
retTy: Ty.Void,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "__add",
|
|
||||||
ty: Ty.create("Fn", {
|
|
||||||
params: [Ty.Int, Ty.Int],
|
|
||||||
retTy: Ty.Int,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@ -1,7 +1,6 @@
|
|||||||
import * as ast from "../ast.ts";
|
import * as ast from "../ast.ts";
|
||||||
import { FileReporter, Loc } from "../diagnostics.ts";
|
import { FileReporter, Loc } from "../diagnostics.ts";
|
||||||
import { Ty } from "../ty.ts";
|
import { Ty } from "../ty.ts";
|
||||||
import { builtins } from "./builtins.ts";
|
|
||||||
import { Syms } from "./resolve.ts";
|
import { Syms } from "./resolve.ts";
|
||||||
|
|
||||||
export class Tys {
|
export class Tys {
|
||||||
@ -131,7 +130,8 @@ class Checker {
|
|||||||
return Ty.Bool;
|
return Ty.Bool;
|
||||||
}
|
}
|
||||||
if (sym.tag === "Builtin") {
|
if (sym.tag === "Builtin") {
|
||||||
return builtins.find((s) => s.id === sym.id)!.ty;
|
this.error(node.loc, `invalid use of builtin '${sym.id}'`);
|
||||||
|
this.fail();
|
||||||
}
|
}
|
||||||
if (sym.tag === "FnParam") {
|
if (sym.tag === "FnParam") {
|
||||||
return this.tys.expr(sym.param);
|
return this.tys.expr(sym.param);
|
||||||
@ -308,6 +308,17 @@ class Checker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private checkCall(node: ast.NodeWithKind<"CallExpr">): Ty {
|
private checkCall(node: ast.NodeWithKind<"CallExpr">): Ty {
|
||||||
|
if (node.kind.value.is("IdentExpr")) {
|
||||||
|
const sym = this.syms.get(node.kind.value);
|
||||||
|
if (sym && sym.tag === "Builtin") {
|
||||||
|
if (sym.id === "debug_print") {
|
||||||
|
const _argTys = node.kind.args
|
||||||
|
.map((arg) => this.tys.expr(arg));
|
||||||
|
return Ty.Void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const calleeTy = this.tys.expr(node.kind.value);
|
const calleeTy = this.tys.expr(node.kind.value);
|
||||||
|
|
||||||
const callableTy = calleeTy.is("Fn")
|
const callableTy = calleeTy.is("Fn")
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import * as ast from "../ast.ts";
|
import * as ast from "../ast.ts";
|
||||||
import { FileReporter } from "../diagnostics.ts";
|
import { FileReporter } from "../diagnostics.ts";
|
||||||
import { builtins } from "./builtins.ts";
|
|
||||||
|
|
||||||
export class Syms {
|
export class Syms {
|
||||||
constructor(
|
constructor(
|
||||||
@ -113,12 +112,9 @@ export function resolve(
|
|||||||
class ResolverSyms {
|
class ResolverSyms {
|
||||||
static root(): ResolverSyms {
|
static root(): ResolverSyms {
|
||||||
return new ResolverSyms(
|
return new ResolverSyms(
|
||||||
new Map(
|
new Map([
|
||||||
builtins.map<[string, Sym]>((sym) => [
|
["debug_print", { tag: "Builtin", id: "debug_print" }],
|
||||||
sym.id,
|
]),
|
||||||
{ tag: "Builtin", id: sym.id },
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
305
src/middle.ts
305
src/middle.ts
@ -57,109 +57,120 @@ class FnLowerer {
|
|||||||
return this.lowerLetStmt(stmt);
|
return this.lowerLetStmt(stmt);
|
||||||
}
|
}
|
||||||
if (stmt.is("ReturnStmt")) {
|
if (stmt.is("ReturnStmt")) {
|
||||||
const source = stmt.kind.expr
|
return this.lowerReturnStmt(stmt);
|
||||||
? this.lowerExpr(stmt.kind.expr)
|
|
||||||
: this.makeVoid();
|
|
||||||
this.pushInst(Ty.Void, "Return", { source });
|
|
||||||
this.bbs.push(new BasicBlock());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (stmt.is("IfStmt")) {
|
if (stmt.is("IfStmt")) {
|
||||||
const cond = this.lowerExpr(stmt.kind.cond);
|
return this.lowerIfStmt(stmt);
|
||||||
const condBlock = this.bbs.at(-1)!;
|
|
||||||
|
|
||||||
this.bbs.push(new BasicBlock());
|
|
||||||
const truthy = this.bbs.at(-1)!;
|
|
||||||
this.lowerBlock(stmt.kind.truthy.as("Block"));
|
|
||||||
const truthyEnd = this.bbs.at(-1)!;
|
|
||||||
|
|
||||||
let falsy: BasicBlock | null = null;
|
|
||||||
let falsyEnd: BasicBlock | null = null;
|
|
||||||
|
|
||||||
if (stmt.kind.falsy) {
|
|
||||||
this.bbs.push(new BasicBlock());
|
|
||||||
falsy = this.bbs.at(-1)!;
|
|
||||||
this.lowerBlock(stmt.kind.falsy.as("Block"));
|
|
||||||
falsyEnd = this.bbs.at(-1)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.bbs.push(new BasicBlock());
|
|
||||||
const done = this.bbs.at(-1)!;
|
|
||||||
|
|
||||||
condBlock.insts.push(
|
|
||||||
new Inst(Ty.Void, {
|
|
||||||
tag: "Branch",
|
|
||||||
cond,
|
|
||||||
truthy,
|
|
||||||
falsy: falsy ?? done,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
truthyEnd.insts.push(
|
|
||||||
new Inst(Ty.Void, { tag: "Jump", target: falsy ?? done }),
|
|
||||||
);
|
|
||||||
falsyEnd?.insts.push(
|
|
||||||
new Inst(Ty.Void, { tag: "Jump", target: done }),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (stmt.is("WhileStmt")) {
|
if (stmt.is("WhileStmt")) {
|
||||||
const before = this.bbs.at(-1)!;
|
return this.lowerWhileStmt(stmt);
|
||||||
|
|
||||||
this.bbs.push(new BasicBlock());
|
|
||||||
const body = this.bbs.at(-1)!;
|
|
||||||
|
|
||||||
const after = new BasicBlock();
|
|
||||||
this.loopEndMap.set(stmt.id, after);
|
|
||||||
this.lowerBlock(stmt.kind.body.as("Block"));
|
|
||||||
|
|
||||||
const bodyEnd = this.bbs.at(-1)!;
|
|
||||||
|
|
||||||
this.bbs.push(new BasicBlock());
|
|
||||||
const condBlock = this.bbs.at(-1)!;
|
|
||||||
const cond = this.lowerExpr(stmt.kind.cond);
|
|
||||||
const condBlockEnd = this.bbs.at(-1)!;
|
|
||||||
|
|
||||||
this.bbs.push(after);
|
|
||||||
|
|
||||||
before.insts.push(
|
|
||||||
new Inst(Ty.Void, { tag: "Jump", target: condBlock }),
|
|
||||||
);
|
|
||||||
condBlockEnd.insts.push(
|
|
||||||
new Inst(Ty.Void, {
|
|
||||||
tag: "Branch",
|
|
||||||
cond: cond,
|
|
||||||
truthy: body,
|
|
||||||
falsy: after,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
bodyEnd.insts.push(
|
|
||||||
new Inst(Ty.Void, { tag: "Jump", target: condBlock }),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (stmt.is("BreakStmt")) {
|
if (stmt.is("BreakStmt")) {
|
||||||
const sym = this.syms.get(stmt);
|
return this.lowerBreakStmt(stmt);
|
||||||
if (sym.tag !== "Loop") {
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
const loopEnd = this.loopEndMap.get(sym.stmt.id);
|
|
||||||
if (!loopEnd) {
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
this.pushInst(Ty.Void, "Jump", { target: loopEnd });
|
|
||||||
this.bbs.push(new BasicBlock());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (stmt.is("AssignStmt")) {
|
if (stmt.is("AssignStmt")) {
|
||||||
return this.lowerAssignStmt(stmt);
|
return this.lowerAssignStmt(stmt);
|
||||||
}
|
}
|
||||||
if (stmt.is("ExprStmt")) {
|
if (stmt.is("ExprStmt")) {
|
||||||
this.lowerExpr(stmt.kind.expr);
|
return this.lowerExpr(stmt.kind.expr);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
throw new Error(`'${stmt.kind.tag}' not handled`);
|
throw new Error(`'${stmt.kind.tag}' not handled`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private lowerReturnStmt(stmt: ast.NodeWithKind<"ReturnStmt">) {
|
||||||
|
const source = stmt.kind.expr
|
||||||
|
? this.lowerExpr(stmt.kind.expr)
|
||||||
|
: this.makeVoid();
|
||||||
|
this.pushInst(Ty.Void, "Return", { source });
|
||||||
|
this.bbs.push(new BasicBlock());
|
||||||
|
}
|
||||||
|
|
||||||
|
private lowerIfStmt(stmt: ast.NodeWithKind<"IfStmt">) {
|
||||||
|
const cond = this.lowerExpr(stmt.kind.cond);
|
||||||
|
const condBlock = this.bbs.at(-1)!;
|
||||||
|
|
||||||
|
this.bbs.push(new BasicBlock());
|
||||||
|
const truthy = this.bbs.at(-1)!;
|
||||||
|
this.lowerBlock(stmt.kind.truthy.as("Block"));
|
||||||
|
const truthyEnd = this.bbs.at(-1)!;
|
||||||
|
|
||||||
|
let falsy: BasicBlock | null = null;
|
||||||
|
let falsyEnd: BasicBlock | null = null;
|
||||||
|
|
||||||
|
if (stmt.kind.falsy) {
|
||||||
|
this.bbs.push(new BasicBlock());
|
||||||
|
falsy = this.bbs.at(-1)!;
|
||||||
|
this.lowerBlock(stmt.kind.falsy.as("Block"));
|
||||||
|
falsyEnd = this.bbs.at(-1)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bbs.push(new BasicBlock());
|
||||||
|
const done = this.bbs.at(-1)!;
|
||||||
|
|
||||||
|
condBlock.insts.push(
|
||||||
|
new Inst(Ty.Void, {
|
||||||
|
tag: "Branch",
|
||||||
|
cond,
|
||||||
|
truthy,
|
||||||
|
falsy: falsy ?? done,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
truthyEnd.insts.push(
|
||||||
|
new Inst(Ty.Void, { tag: "Jump", target: falsy ?? done }),
|
||||||
|
);
|
||||||
|
falsyEnd?.insts.push(
|
||||||
|
new Inst(Ty.Void, { tag: "Jump", target: done }),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private lowerWhileStmt(stmt: ast.NodeWithKind<"WhileStmt">) {
|
||||||
|
const before = this.bbs.at(-1)!;
|
||||||
|
|
||||||
|
this.bbs.push(new BasicBlock());
|
||||||
|
const body = this.bbs.at(-1)!;
|
||||||
|
|
||||||
|
const after = new BasicBlock();
|
||||||
|
this.loopEndMap.set(stmt.id, after);
|
||||||
|
this.lowerBlock(stmt.kind.body.as("Block"));
|
||||||
|
|
||||||
|
const bodyEnd = this.bbs.at(-1)!;
|
||||||
|
|
||||||
|
this.bbs.push(new BasicBlock());
|
||||||
|
const condBlock = this.bbs.at(-1)!;
|
||||||
|
const cond = this.lowerExpr(stmt.kind.cond);
|
||||||
|
const condBlockEnd = this.bbs.at(-1)!;
|
||||||
|
|
||||||
|
this.bbs.push(after);
|
||||||
|
|
||||||
|
before.insts.push(
|
||||||
|
new Inst(Ty.Void, { tag: "Jump", target: condBlock }),
|
||||||
|
);
|
||||||
|
condBlockEnd.insts.push(
|
||||||
|
new Inst(Ty.Void, {
|
||||||
|
tag: "Branch",
|
||||||
|
cond: cond,
|
||||||
|
truthy: body,
|
||||||
|
falsy: after,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
bodyEnd.insts.push(
|
||||||
|
new Inst(Ty.Void, { tag: "Jump", target: condBlock }),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private lowerBreakStmt(stmt: ast.NodeWithKind<"BreakStmt">) {
|
||||||
|
const sym = this.syms.get(stmt);
|
||||||
|
if (sym.tag !== "Loop") {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
const loopEnd = this.loopEndMap.get(sym.stmt.id);
|
||||||
|
if (!loopEnd) {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
this.pushInst(Ty.Void, "Jump", { target: loopEnd });
|
||||||
|
this.bbs.push(new BasicBlock());
|
||||||
|
}
|
||||||
|
|
||||||
private lowerLetStmt(stmt: ast.NodeWithKind<"LetStmt">) {
|
private lowerLetStmt(stmt: ast.NodeWithKind<"LetStmt">) {
|
||||||
const ty = this.tys.expr(stmt.kind.param);
|
const ty = this.tys.expr(stmt.kind.param);
|
||||||
const expr = this.lowerExpr(stmt.kind.expr);
|
const expr = this.lowerExpr(stmt.kind.expr);
|
||||||
@ -291,11 +302,7 @@ class FnLowerer {
|
|||||||
if (expr.kind.value.is("IdentExpr")) {
|
if (expr.kind.value.is("IdentExpr")) {
|
||||||
const sym = this.syms.get(expr.kind.value);
|
const sym = this.syms.get(expr.kind.value);
|
||||||
if (sym.tag === "Builtin") {
|
if (sym.tag === "Builtin") {
|
||||||
if (sym.id === "__add") {
|
if (sym.id === "debug_print") {
|
||||||
const [left, right] = args;
|
|
||||||
return this.pushInst(ty, "Add", { left, right });
|
|
||||||
}
|
|
||||||
if (sym.id === "print_int") {
|
|
||||||
return this.pushInst(ty, "DebugPrint", { args });
|
return this.pushInst(ty, "DebugPrint", { args });
|
||||||
}
|
}
|
||||||
throw new Error(`builtin '${sym.id}' not handled`);
|
throw new Error(`builtin '${sym.id}' not handled`);
|
||||||
@ -306,60 +313,7 @@ class FnLowerer {
|
|||||||
return this.pushInst(ty, "Call", { callee, args });
|
return this.pushInst(ty, "Call", { callee, args });
|
||||||
}
|
}
|
||||||
if (expr.is("UnaryExpr")) {
|
if (expr.is("UnaryExpr")) {
|
||||||
const resultTy = this.tys.expr(expr);
|
return this.lowerUnaryExpr(expr);
|
||||||
const operandTy = this.tys.expr(expr.kind.expr);
|
|
||||||
if (
|
|
||||||
expr.kind.op === "Negate" &&
|
|
||||||
operandTy.compatibleWith(Ty.Int) &&
|
|
||||||
resultTy.compatibleWith(Ty.Int)
|
|
||||||
) {
|
|
||||||
const operand = this.lowerExpr(expr.kind.expr);
|
|
||||||
return this.pushInst(Ty.Int, "Negate", { source: operand });
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
expr.kind.op === "Not" &&
|
|
||||||
operandTy.compatibleWith(Ty.Bool) &&
|
|
||||||
resultTy.compatibleWith(Ty.Bool)
|
|
||||||
) {
|
|
||||||
const operand = this.lowerExpr(expr.kind.expr);
|
|
||||||
return this.pushInst(Ty.Bool, "Not", { source: operand });
|
|
||||||
}
|
|
||||||
if (expr.kind.op === "Ref" || expr.kind.op === "RefMut") {
|
|
||||||
const place = expr.kind.expr;
|
|
||||||
if (place.is("IdentExpr")) {
|
|
||||||
const sym = this.syms.get(place);
|
|
||||||
if (sym.tag === "Let") {
|
|
||||||
const local = this.localMap.get(sym.param.id);
|
|
||||||
if (!local) {
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
throw new Error(
|
|
||||||
`${expr.kind.op} with sym ${sym.tag} not handled`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (place.is("IndexExpr")) {
|
|
||||||
const placeTy = this.tys.expr(place);
|
|
||||||
const placeInst = this.lowerPlace(place);
|
|
||||||
if (placeTy.is("Slice")) {
|
|
||||||
return placeInst;
|
|
||||||
}
|
|
||||||
return this.pushInst(placeTy, "Load", {
|
|
||||||
source: placeInst,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
throw new Error(
|
|
||||||
`${expr.kind.op} with place ${place.kind.tag} not handled`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (expr.kind.op === "Deref") {
|
|
||||||
const source = this.lowerExpr(expr.kind.expr);
|
|
||||||
return this.pushInst(resultTy, "Load", { source });
|
|
||||||
}
|
|
||||||
throw new Error(
|
|
||||||
`'${expr.kind.op}' with '${resultTy.pretty()}' not handled`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (expr.is("BinaryExpr")) {
|
if (expr.is("BinaryExpr")) {
|
||||||
const resultTy = this.tys.expr(expr);
|
const resultTy = this.tys.expr(expr);
|
||||||
@ -384,6 +338,63 @@ class FnLowerer {
|
|||||||
throw new Error(`'${expr.kind.tag}' not handled`);
|
throw new Error(`'${expr.kind.tag}' not handled`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private lowerUnaryExpr(expr: ast.NodeWithKind<"UnaryExpr">) {
|
||||||
|
const resultTy = this.tys.expr(expr);
|
||||||
|
const operandTy = this.tys.expr(expr.kind.expr);
|
||||||
|
if (
|
||||||
|
expr.kind.op === "Negate" &&
|
||||||
|
operandTy.compatibleWith(Ty.Int) &&
|
||||||
|
resultTy.compatibleWith(Ty.Int)
|
||||||
|
) {
|
||||||
|
const operand = this.lowerExpr(expr.kind.expr);
|
||||||
|
return this.pushInst(Ty.Int, "Negate", { source: operand });
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
expr.kind.op === "Not" &&
|
||||||
|
operandTy.compatibleWith(Ty.Bool) &&
|
||||||
|
resultTy.compatibleWith(Ty.Bool)
|
||||||
|
) {
|
||||||
|
const operand = this.lowerExpr(expr.kind.expr);
|
||||||
|
return this.pushInst(Ty.Bool, "Not", { source: operand });
|
||||||
|
}
|
||||||
|
if (expr.kind.op === "Ref" || expr.kind.op === "RefMut") {
|
||||||
|
const place = expr.kind.expr;
|
||||||
|
if (place.is("IdentExpr")) {
|
||||||
|
const sym = this.syms.get(place);
|
||||||
|
if (sym.tag === "Let") {
|
||||||
|
const local = this.localMap.get(sym.param.id);
|
||||||
|
if (!local) {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
return local;
|
||||||
|
}
|
||||||
|
throw new Error(
|
||||||
|
`${expr.kind.op} with sym ${sym.tag} not handled`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (place.is("IndexExpr")) {
|
||||||
|
const placeTy = this.tys.expr(place);
|
||||||
|
const placeInst = this.lowerPlace(place);
|
||||||
|
if (placeTy.is("Slice")) {
|
||||||
|
return placeInst;
|
||||||
|
}
|
||||||
|
return this.pushInst(placeTy, "Load", {
|
||||||
|
source: placeInst,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
throw new Error(
|
||||||
|
`${expr.kind.op} with place ${place.kind.tag} not handled`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (expr.kind.op === "Deref") {
|
||||||
|
const source = this.lowerExpr(expr.kind.expr);
|
||||||
|
return this.pushInst(resultTy, "Load", { source });
|
||||||
|
}
|
||||||
|
throw new Error(
|
||||||
|
`'${expr.kind.op}' with '${resultTy.pretty()}' not handled`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private makeVoid(): Inst {
|
private makeVoid(): Inst {
|
||||||
return this.pushInst(Ty.Void, "Void", {});
|
return this.pushInst(Ty.Void, "Void", {});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,20 +5,20 @@ fn main()
|
|||||||
|
|
||||||
let elem: int = array[0];
|
let elem: int = array[0];
|
||||||
// expect: 1
|
// expect: 1
|
||||||
print_int(elem);
|
debug_print(elem);
|
||||||
|
|
||||||
let ptr_to_array: *[int; 3] = &array;
|
let ptr_to_array: *[int; 3] = &array;
|
||||||
// expect: 2
|
// expect: 2
|
||||||
print_int(ptr_to_array.*[1]);
|
debug_print(ptr_to_array.*[1]);
|
||||||
|
|
||||||
let slice: *[int] = &array[..];
|
let slice: *[int] = &array[..];
|
||||||
// expect: 3
|
// expect: 3
|
||||||
print_int(slice.*[2]);
|
debug_print(slice.*[2]);
|
||||||
|
|
||||||
let slice_mut: *mut [int] = &mut array[1..3];
|
let slice_mut: *mut [int] = &mut array[1..3];
|
||||||
slice_mut.*[0] = 4;
|
slice_mut.*[0] = 4;
|
||||||
// expect: 4
|
// expect: 4
|
||||||
print_int(array[1]);
|
debug_print(array[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim: syntax=rust commentstring=//\ %s
|
// vim: syntax=rust commentstring=//\ %s
|
||||||
|
|||||||
@ -4,6 +4,6 @@ fn main()
|
|||||||
{
|
{
|
||||||
let v: int = 123;
|
let v: int = 123;
|
||||||
v = 456;
|
v = 456;
|
||||||
print_int(v);
|
debug_print(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ fn main()
|
|||||||
a = 3;
|
a = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_int(a);
|
debug_print(a);
|
||||||
|
|
||||||
if false {
|
if false {
|
||||||
a = 4;
|
a = 4;
|
||||||
@ -21,5 +21,5 @@ fn main()
|
|||||||
a = 5;
|
a = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_int(a);
|
debug_print(a);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ fn main()
|
|||||||
a = a + 1;
|
a = a + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_int(a);
|
debug_print(a);
|
||||||
|
|
||||||
while a < 10 {
|
while a < 10 {
|
||||||
if a >= 8 {
|
if a >= 8 {
|
||||||
@ -18,5 +18,5 @@ fn main()
|
|||||||
a = a + 1;
|
a = a + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_int(a);
|
debug_print(a);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,20 +13,20 @@ fn main()
|
|||||||
let a = 5;
|
let a = 5;
|
||||||
let b = 3;
|
let b = 3;
|
||||||
|
|
||||||
print_int(a + b);
|
debug_print(a + b);
|
||||||
print_int(a - b);
|
debug_print(a - b);
|
||||||
print_int(a * b);
|
debug_print(a * b);
|
||||||
print_int(a * b / 2);
|
debug_print(a * b / 2);
|
||||||
print_int(a % b);
|
debug_print(a % b);
|
||||||
print_int(-a);
|
debug_print(-a);
|
||||||
|
|
||||||
let c = false;
|
let c = false;
|
||||||
|
|
||||||
if not c {
|
if not c {
|
||||||
print_int(123);
|
debug_print(123);
|
||||||
}
|
}
|
||||||
|
|
||||||
print_int(2 * 3 + 4);
|
debug_print(2 * 3 + 4);
|
||||||
print_int(2 * (3 + 4));
|
debug_print(2 * (3 + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,21 +9,21 @@ fn main()
|
|||||||
let a = 1;
|
let a = 1;
|
||||||
let b: *int = &a;
|
let b: *int = &a;
|
||||||
// expect: 1
|
// expect: 1
|
||||||
print_int(*b);
|
debug_print(*b);
|
||||||
|
|
||||||
a = 2;
|
a = 2;
|
||||||
// expect: 2
|
// expect: 2
|
||||||
print_int(*b);
|
debug_print(*b);
|
||||||
|
|
||||||
let c: *mut int = &mut a;
|
let c: *mut int = &mut a;
|
||||||
*c = 3;
|
*c = 3;
|
||||||
// expect: 3
|
// expect: 3
|
||||||
print_int(a);
|
debug_print(a);
|
||||||
// expect: 3
|
// expect: 3
|
||||||
print_int(*c);
|
debug_print(*c);
|
||||||
|
|
||||||
change_to(&mut a, 4);
|
change_to(&mut a, 4);
|
||||||
// expect: 4
|
// expect: 4
|
||||||
print_int(a);
|
debug_print(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user