mirror of
https://git.sfja.dk/Mikkel/slige.git
synced 2025-07-04 05:26:56 +01:00
Compare commits
No commits in common. "ca1d67a54a028cf4f423d15d48e4e4ae68f4f48a" and "7b879d30be1475c95a855945b8f3e84d81ffd191" have entirely different histories.
ca1d67a54a
...
7b879d30be
@ -10,7 +10,6 @@ export type Mod = {
|
|||||||
export type Stmt = {
|
export type Stmt = {
|
||||||
kind: StmtKind;
|
kind: StmtKind;
|
||||||
pos: Pos;
|
pos: Pos;
|
||||||
details?: StmtDetails;
|
|
||||||
id: number;
|
id: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -28,6 +27,7 @@ export type StmtKind =
|
|||||||
params: Param[];
|
params: Param[];
|
||||||
returnType?: EType;
|
returnType?: EType;
|
||||||
body: Expr;
|
body: Expr;
|
||||||
|
anno?: Anno;
|
||||||
vtype?: VType;
|
vtype?: VType;
|
||||||
}
|
}
|
||||||
| { type: "let"; param: Param; value: Expr }
|
| { type: "let"; param: Param; value: Expr }
|
||||||
@ -36,11 +36,6 @@ export type StmtKind =
|
|||||||
|
|
||||||
export type AssignType = "=" | "+=" | "-=";
|
export type AssignType = "=" | "+=" | "-=";
|
||||||
|
|
||||||
export type StmtDetails = {
|
|
||||||
pub: boolean;
|
|
||||||
annos: Anno[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Expr = {
|
export type Expr = {
|
||||||
kind: ExprKind;
|
kind: ExprKind;
|
||||||
pos: Pos;
|
pos: Pos;
|
||||||
@ -152,17 +147,17 @@ export type GenericParam = {
|
|||||||
|
|
||||||
export type Anno = {
|
export type Anno = {
|
||||||
ident: string;
|
ident: string;
|
||||||
args: Expr[];
|
values: Expr[];
|
||||||
pos: Pos;
|
pos: Pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class AstCreator {
|
export class AstCreator {
|
||||||
private nextNodeId = 0;
|
private nextNodeId = 0;
|
||||||
|
|
||||||
public stmt(kind: StmtKind, pos: Pos, details?: StmtDetails): Stmt {
|
public stmt(kind: StmtKind, pos: Pos): Stmt {
|
||||||
const id = this.nextNodeId;
|
const id = this.nextNodeId;
|
||||||
this.nextNodeId += 1;
|
this.nextNodeId += 1;
|
||||||
return { kind, pos, details, id };
|
return { kind, pos, id };
|
||||||
}
|
}
|
||||||
|
|
||||||
public expr(kind: ExprKind, pos: Pos): Expr {
|
public expr(kind: ExprKind, pos: Pos): Expr {
|
||||||
@ -177,21 +172,3 @@ export class AstCreator {
|
|||||||
return { kind, pos, id };
|
return { kind, pos, id };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AnnoView {
|
|
||||||
public constructor(private details?: StmtDetails) {}
|
|
||||||
|
|
||||||
public has(...idents: string[]): boolean {
|
|
||||||
return this.details?.annos.some((anno) =>
|
|
||||||
idents.some((ident) => anno.ident === ident)
|
|
||||||
) ?? false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get(ident: string): Anno {
|
|
||||||
const anno = this.details?.annos.find((anno) => anno.ident === ident);
|
|
||||||
if (!anno) {
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
return anno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { AnnoView, EType, Expr, Stmt, Sym } from "./ast.ts";
|
import { EType, Expr, Stmt, Sym } from "./ast.ts";
|
||||||
import { printStackTrace, Reporter } from "./info.ts";
|
import { printStackTrace, Reporter } from "./info.ts";
|
||||||
import { Pos } from "./token.ts";
|
import { Pos } from "./token.ts";
|
||||||
import {
|
import {
|
||||||
@ -162,12 +162,12 @@ export class Checker {
|
|||||||
throw new Error();
|
throw new Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
const annos = new AnnoView(stmt.details);
|
if (
|
||||||
if (annos.has("builtin", "remainder")) {
|
stmt.kind.anno?.ident === "remainder" ||
|
||||||
// NOTE: handled in lowerer
|
stmt.kind.anno?.ident === "builtin"
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { returnType } = stmt.kind.vtype!;
|
const { returnType } = stmt.kind.vtype!;
|
||||||
if (returnType.type === "error") return returnType;
|
if (returnType.type === "error") return returnType;
|
||||||
this.fnReturnStack.push(returnType);
|
this.fnReturnStack.push(returnType);
|
||||||
|
@ -48,8 +48,6 @@ export class Lexer {
|
|||||||
"for",
|
"for",
|
||||||
"in",
|
"in",
|
||||||
"mod",
|
"mod",
|
||||||
"pub",
|
|
||||||
"use",
|
|
||||||
];
|
];
|
||||||
if (keywords.includes(value)) {
|
if (keywords.includes(value)) {
|
||||||
return this.token(value, pos);
|
return this.token(value, pos);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Builtins, Ops } from "./arch.ts";
|
import { Builtins, Ops } from "./arch.ts";
|
||||||
import { Assembler, Label } from "./assembler.ts";
|
import { Assembler, Label } from "./assembler.ts";
|
||||||
import { AnnoView, Expr, Stmt } from "./ast.ts";
|
import { Expr, Stmt } from "./ast.ts";
|
||||||
import { LocalLeaf, Locals, LocalsFnRoot } from "./lowerer_locals.ts";
|
import { LocalLeaf, Locals, LocalsFnRoot } from "./lowerer_locals.ts";
|
||||||
import { MonoCallNameGenMap, MonoFn, MonoFnsMap } from "./mono.ts";
|
import { MonoCallNameGenMap, MonoFn, MonoFnsMap } from "./mono.ts";
|
||||||
import { Pos } from "./token.ts";
|
import { Pos } from "./token.ts";
|
||||||
@ -111,15 +111,9 @@ class MonoFnLowerer {
|
|||||||
for (const { ident } of stmt.kind.params) {
|
for (const { ident } of stmt.kind.params) {
|
||||||
this.locals.allocSym(ident);
|
this.locals.allocSym(ident);
|
||||||
}
|
}
|
||||||
|
if (stmt.kind.anno?.ident === "builtin") {
|
||||||
const annos = new AnnoView(stmt.details);
|
this.lowerFnBuiltinBody(stmt.kind.anno.values);
|
||||||
if (annos.has("builtin")) {
|
} else if (stmt.kind.anno?.ident === "remainder") {
|
||||||
const anno = annos.get("builtin");
|
|
||||||
if (!anno) {
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
this.lowerFnBuiltinBody(anno.args);
|
|
||||||
} else if (annos.has("remainder")) {
|
|
||||||
this.program.add(Ops.Remainder);
|
this.program.add(Ops.Remainder);
|
||||||
} else {
|
} else {
|
||||||
this.lowerExpr(stmt.kind.body);
|
this.lowerExpr(stmt.kind.body);
|
||||||
|
@ -10,7 +10,6 @@ import {
|
|||||||
GenericParam,
|
GenericParam,
|
||||||
Param,
|
Param,
|
||||||
Stmt,
|
Stmt,
|
||||||
StmtDetails,
|
|
||||||
StmtKind,
|
StmtKind,
|
||||||
UnaryType,
|
UnaryType,
|
||||||
} from "./ast.ts";
|
} from "./ast.ts";
|
||||||
@ -38,18 +37,18 @@ export class Parser {
|
|||||||
private parseStmts(): Stmt[] {
|
private parseStmts(): Stmt[] {
|
||||||
const stmts: Stmt[] = [];
|
const stmts: Stmt[] = [];
|
||||||
while (!this.done()) {
|
while (!this.done()) {
|
||||||
stmts.push(this.parseStmt());
|
stmts.push(this.parseModStmt());
|
||||||
}
|
}
|
||||||
return stmts;
|
return stmts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseStmt(): Stmt {
|
private parseModStmt(): Stmt {
|
||||||
if (
|
if (this.test("mod")) {
|
||||||
["#", "pub", "mod", "fn"].some((tt) => this.test(tt))
|
return (this.parseMod());
|
||||||
) {
|
} else if (this.test("fn")) {
|
||||||
return this.parseItemStmt();
|
return (this.parseFn());
|
||||||
} else if (
|
} else if (
|
||||||
["let", "return", "break"].some((tt) => this.test(tt))
|
this.test("let") || this.test("return") || this.test("break")
|
||||||
) {
|
) {
|
||||||
const expr = this.parseSingleLineBlockStmt();
|
const expr = this.parseSingleLineBlockStmt();
|
||||||
this.eatSemicolon();
|
this.eatSemicolon();
|
||||||
@ -66,6 +65,42 @@ export class Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private parseMod(): Stmt {
|
||||||
|
const pos = this.pos();
|
||||||
|
this.step();
|
||||||
|
if (!this.test("ident")) {
|
||||||
|
this.report("expected 'ident'");
|
||||||
|
return this.stmt({ type: "error" }, pos);
|
||||||
|
}
|
||||||
|
const ident = this.current().identValue!;
|
||||||
|
this.step();
|
||||||
|
if (this.test("string")) {
|
||||||
|
const filePath = this.current().stringValue!;
|
||||||
|
this.step();
|
||||||
|
this.eatSemicolon();
|
||||||
|
return this.stmt({ type: "mod_file", ident, filePath }, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.test("{")) {
|
||||||
|
this.report("expected '{' or 'string'");
|
||||||
|
return this.stmt({ type: "error" }, pos);
|
||||||
|
}
|
||||||
|
this.step();
|
||||||
|
|
||||||
|
const stmts: Stmt[] = [];
|
||||||
|
while (!this.done() && !this.test("}")) {
|
||||||
|
stmts.push(this.parseModStmt());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.test("}")) {
|
||||||
|
this.report("expected '}'");
|
||||||
|
return this.stmt({ type: "error" }, pos);
|
||||||
|
}
|
||||||
|
this.step();
|
||||||
|
|
||||||
|
return this.stmt({ type: "mod_block", ident, stmts }, pos);
|
||||||
|
}
|
||||||
|
|
||||||
private parseMultiLineBlockExpr(): Expr {
|
private parseMultiLineBlockExpr(): Expr {
|
||||||
const pos = this.pos();
|
const pos = this.pos();
|
||||||
if (this.test("{")) {
|
if (this.test("{")) {
|
||||||
@ -125,14 +160,13 @@ export class Parser {
|
|||||||
this.step();
|
this.step();
|
||||||
return this.expr({ type: "block", stmts }, pos);
|
return this.expr({ type: "block", stmts }, pos);
|
||||||
} else if (
|
} else if (
|
||||||
["#", "pub", "mod", "fn"].some((tt) => this.test(tt))
|
this.test("return") || this.test("break") || this.test("let")
|
||||||
) {
|
|
||||||
stmts.push(this.parseItemStmt());
|
|
||||||
} else if (
|
|
||||||
["let", "return", "break"].some((tt) => this.test(tt))
|
|
||||||
) {
|
) {
|
||||||
stmts.push(this.parseSingleLineBlockStmt());
|
stmts.push(this.parseSingleLineBlockStmt());
|
||||||
this.eatSemicolon();
|
this.eatSemicolon();
|
||||||
|
} else if (this.test("fn")) {
|
||||||
|
stmts.push(this.parseSingleLineBlockStmt());
|
||||||
|
stmts.push(this.parseFn());
|
||||||
} else if (
|
} else if (
|
||||||
["{", "if", "loop", "while", "for"].some((tt) => this.test(tt))
|
["{", "if", "loop", "while", "for"].some((tt) => this.test(tt))
|
||||||
) {
|
) {
|
||||||
@ -176,103 +210,7 @@ export class Parser {
|
|||||||
return this.expr({ type: "error" }, pos);
|
return this.expr({ type: "error" }, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseItemStmt(
|
private parseFn(): Stmt {
|
||||||
pos = this.pos(),
|
|
||||||
details: StmtDetails = {
|
|
||||||
pub: false,
|
|
||||||
annos: [],
|
|
||||||
},
|
|
||||||
): Stmt {
|
|
||||||
const spos = this.pos();
|
|
||||||
if (this.test("#") && !details.pub) {
|
|
||||||
this.step();
|
|
||||||
if (!this.test("[")) {
|
|
||||||
this.report("expected '['");
|
|
||||||
return this.stmt({ type: "error" }, spos);
|
|
||||||
}
|
|
||||||
this.step();
|
|
||||||
if (!this.test("ident")) {
|
|
||||||
this.report("expected 'ident'");
|
|
||||||
return this.stmt({ type: "error" }, spos);
|
|
||||||
}
|
|
||||||
const ident = this.current().identValue!;
|
|
||||||
this.step();
|
|
||||||
const args: Expr[] = [];
|
|
||||||
if (this.test("(")) {
|
|
||||||
this.step();
|
|
||||||
if (!this.done() && !this.test(")")) {
|
|
||||||
args.push(this.parseExpr());
|
|
||||||
while (this.test(",")) {
|
|
||||||
this.step();
|
|
||||||
args.push(this.parseExpr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!this.test(")")) {
|
|
||||||
this.report("expected ')'");
|
|
||||||
return this.stmt({ type: "error" }, spos);
|
|
||||||
}
|
|
||||||
this.step();
|
|
||||||
}
|
|
||||||
if (!this.test("]")) {
|
|
||||||
this.report("expected ']'");
|
|
||||||
return this.stmt({ type: "error" }, spos);
|
|
||||||
}
|
|
||||||
this.step();
|
|
||||||
const anno = { ident, args, pos: spos };
|
|
||||||
return this.parseItemStmt(pos, {
|
|
||||||
...details,
|
|
||||||
annos: [...details.annos, anno],
|
|
||||||
});
|
|
||||||
} else if (this.test("pub") && !details.pub) {
|
|
||||||
this.step();
|
|
||||||
return this.parseItemStmt(pos, { ...details, pub: true });
|
|
||||||
} else if (this.test("mod")) {
|
|
||||||
return this.parseMod(details);
|
|
||||||
} else if (this.test("fn")) {
|
|
||||||
return this.parseFn(details);
|
|
||||||
} else {
|
|
||||||
this.report("expected item statement");
|
|
||||||
return this.stmt({ type: "error" }, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private parseMod(details: StmtDetails): Stmt {
|
|
||||||
const pos = this.pos();
|
|
||||||
this.step();
|
|
||||||
if (!this.test("ident")) {
|
|
||||||
this.report("expected 'ident'");
|
|
||||||
return this.stmt({ type: "error" }, pos);
|
|
||||||
}
|
|
||||||
const ident = this.current().identValue!;
|
|
||||||
this.step();
|
|
||||||
if (this.test("string")) {
|
|
||||||
const filePath = this.current().stringValue!;
|
|
||||||
this.step();
|
|
||||||
this.eatSemicolon();
|
|
||||||
return this.stmt({ type: "mod_file", ident, filePath }, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.test("{")) {
|
|
||||||
this.report("expected '{' or 'string'");
|
|
||||||
return this.stmt({ type: "error" }, pos);
|
|
||||||
}
|
|
||||||
this.step();
|
|
||||||
|
|
||||||
const stmts: Stmt[] = [];
|
|
||||||
while (!this.done() && !this.test("}")) {
|
|
||||||
stmts.push(this.parseStmt());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.test("}")) {
|
|
||||||
this.report("expected '}'");
|
|
||||||
return this.stmt({ type: "error" }, pos);
|
|
||||||
}
|
|
||||||
this.step();
|
|
||||||
|
|
||||||
return this.stmt({ type: "mod_block", ident, stmts }, pos, details);
|
|
||||||
}
|
|
||||||
|
|
||||||
private parseFn(details: StmtDetails): Stmt {
|
|
||||||
const pos = this.pos();
|
const pos = this.pos();
|
||||||
this.step();
|
this.step();
|
||||||
if (!this.test("ident")) {
|
if (!this.test("ident")) {
|
||||||
@ -296,6 +234,14 @@ export class Parser {
|
|||||||
returnType = this.parseEType();
|
returnType = this.parseEType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let anno: Anno | undefined;
|
||||||
|
if (this.test("#")) {
|
||||||
|
const result = this.parseAnno();
|
||||||
|
if (!result.ok) {
|
||||||
|
return this.stmt({ type: "error" }, pos);
|
||||||
|
}
|
||||||
|
anno = result.value;
|
||||||
|
}
|
||||||
if (!this.test("{")) {
|
if (!this.test("{")) {
|
||||||
this.report("expected block");
|
this.report("expected block");
|
||||||
return this.stmt({ type: "error" }, pos);
|
return this.stmt({ type: "error" }, pos);
|
||||||
@ -309,12 +255,60 @@ export class Parser {
|
|||||||
params,
|
params,
|
||||||
returnType,
|
returnType,
|
||||||
body,
|
body,
|
||||||
|
anno,
|
||||||
},
|
},
|
||||||
pos,
|
pos,
|
||||||
details,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private parseAnnoArgs(): Expr[] {
|
||||||
|
this.step();
|
||||||
|
if (!this.test("(")) {
|
||||||
|
this.report("expected '('");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
this.step();
|
||||||
|
const annoArgs: Expr[] = [];
|
||||||
|
if (!this.test(")")) {
|
||||||
|
annoArgs.push(this.parseExpr());
|
||||||
|
while (this.test(",")) {
|
||||||
|
this.step();
|
||||||
|
if (this.test(")")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
annoArgs.push(this.parseExpr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.test(")")) {
|
||||||
|
this.report("expected ')'");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
this.step();
|
||||||
|
return annoArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private parseAnno(): Res<Anno> {
|
||||||
|
const pos = this.pos();
|
||||||
|
this.step();
|
||||||
|
if (!this.test("[")) {
|
||||||
|
this.report("expected '['");
|
||||||
|
return { ok: false };
|
||||||
|
}
|
||||||
|
this.step();
|
||||||
|
if (!this.test("ident")) {
|
||||||
|
this.report("expected identifier");
|
||||||
|
return { ok: false };
|
||||||
|
}
|
||||||
|
const ident = this.current().identValue!;
|
||||||
|
const values = this.parseAnnoArgs();
|
||||||
|
if (!this.test("]")) {
|
||||||
|
this.report("expected ']'");
|
||||||
|
return { ok: false };
|
||||||
|
}
|
||||||
|
this.step();
|
||||||
|
return { ok: true, value: { ident, pos, values } };
|
||||||
|
}
|
||||||
|
|
||||||
private parseFnETypeParams(): GenericParam[] {
|
private parseFnETypeParams(): GenericParam[] {
|
||||||
return this.parseDelimitedList(this.parseETypeParam, ">", ",");
|
return this.parseDelimitedList(this.parseETypeParam, ">", ",");
|
||||||
}
|
}
|
||||||
@ -926,8 +920,8 @@ export class Parser {
|
|||||||
printStackTrace();
|
printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
private stmt(kind: StmtKind, pos: Pos, details?: StmtDetails): Stmt {
|
private stmt(kind: StmtKind, pos: Pos): Stmt {
|
||||||
return this.astCreator.stmt(kind, pos, details);
|
return this.astCreator.stmt(kind, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
private expr(kind: ExprKind, pos: Pos): Expr {
|
private expr(kind: ExprKind, pos: Pos): Expr {
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
//
|
fn print(msg: string) #[builtin(print)] {
|
||||||
|
|
||||||
#[builtin(Print)]
|
|
||||||
fn print(msg: string) {
|
|
||||||
"hello" + 0
|
"hello" + 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
63
stdlib.slg
63
stdlib.slg
@ -1,54 +1,33 @@
|
|||||||
|
|
||||||
// stdlib.slg
|
// stdlib.slg
|
||||||
|
|
||||||
#[builtin(Exit)]
|
fn exit(status_code: int) #[builtin(Exit)] {}
|
||||||
fn exit(status_code: int) {}
|
|
||||||
|
|
||||||
#[builtin(Print)]
|
fn print(msg: string) #[builtin(Print)] {}
|
||||||
fn print(msg: string) {}
|
fn println(msg: string) { print(msg + "\n") }
|
||||||
msg + "\n"
|
|
||||||
fn println(msg: string) { print) }
|
|
||||||
|
|
||||||
#[builtin(IntToString)]
|
fn int_to_string(number: int) -> string #[builtin(IntToString)] {}
|
||||||
fn int_to_string(number: int) -> string {}
|
|
||||||
|
|
||||||
#[builtin(StringPushChar)]
|
fn string_push_char(str: string, value: int) -> string #[builtin(StringPushChar)] {}
|
||||||
fn string_push_char(str: string, value: int) -> string {}
|
fn string_char_at(str: string, index: int) -> int #[builtin(StringCharAt)] {}
|
||||||
#[builtin(StringCharAt)]
|
fn string_length(str: string) -> int #[builtin(StringLength)] {}
|
||||||
fn string_char_at(str: string, index: int) -> int {}
|
fn string_to_int(str: string) -> int #[builtin(StringToInt)] {}
|
||||||
#[builtin(StringLength)]
|
|
||||||
fn string_length(str: string) -> int {}
|
|
||||||
#[builtin(StringToInt)]
|
|
||||||
fn string_to_int(str: string) -> int {}
|
|
||||||
|
|
||||||
#[builtin(ArrayNew)]
|
fn array_new<T>() -> [T] #[builtin(ArrayNew)] {}
|
||||||
fn array_new<T>() -> [T] {}
|
fn array_push<T>(array: [T], value: T) #[builtin(ArrayPush)] {}
|
||||||
#[builtin(ArrayPush)]
|
fn array_length<T>(array: [T]) -> int #[builtin(ArrayLength)] {}
|
||||||
fn array_push<T>(array: [T], value: T) {}
|
fn array_at<T>(array: [T], index: int) -> T #[builtin(ArrayAt)] {}
|
||||||
#[builtin(ArrayLength)]
|
|
||||||
fn array_length<T>(array: [T]) -> int {}
|
|
||||||
#[builtin(ArrayAt)]
|
|
||||||
fn array_at<T>(array: [T], index: int) -> T {}
|
|
||||||
|
|
||||||
#[builtin(FileOpen)]
|
fn file_open(filename: string, mode: string) -> int #[builtin(FileOpen)] {}
|
||||||
fn file_open(filename: string, mode: string) -> int {}
|
fn file_close(file: int) #[builtin(FileClose)] {}
|
||||||
#[builtin(FileClose)]
|
fn file_write_string(file: int, content: string) -> int #[builtin(FileWriteString)] {}
|
||||||
fn file_close(file: int) {}
|
fn file_read_char(file: int) -> int #[builtin(FileReadChar)] {}
|
||||||
#[builtin(FileWriteString)]
|
fn file_read_to_string(file: int) -> string #[builtin(FileReadToString)] {}
|
||||||
fn file_write_string(file: int, content: string) -> int {}
|
fn file_flush(file: int) #[builtin(FileFlush)] {}
|
||||||
#[builtin(FileReadChar)]
|
fn file_eof(file: int) -> bool #[builtin(FileEof)] {}
|
||||||
fn file_read_char(file: int) -> int {}
|
|
||||||
#[builtin(FileReadToString)]
|
|
||||||
fn file_read_to_string(file: int) -> string {}
|
|
||||||
#[builtin(FileFlush)]
|
|
||||||
fn file_flush(file: int) {}
|
|
||||||
#[builtin(FileEof)]
|
|
||||||
fn file_eof(file: int) -> bool {}
|
|
||||||
|
|
||||||
#[builtin(IntToString)]
|
fn itos(number: int) -> string #[builtin(IntToString)] {}
|
||||||
fn itos(number: int) -> string {}
|
fn stoi(str: string) -> int #[builtin(StringToInt)] {}
|
||||||
#[builtin(StringToInt)]
|
|
||||||
fn stoi(str: string) -> int {}
|
|
||||||
|
|
||||||
fn stdin() -> int { 0 }
|
fn stdin() -> int { 0 }
|
||||||
fn stdout() -> int { 1 }
|
fn stdout() -> int { 1 }
|
||||||
|
Loading…
Reference in New Issue
Block a user