Skip to content

Commit

Permalink
misc additions
Browse files Browse the repository at this point in the history
- basic cli usage
- basic typechecking abilities (incomplete)
  • Loading branch information
JokeNeverSoke committed Dec 19, 2023
1 parent d4b7134 commit b34eeb7
Show file tree
Hide file tree
Showing 7 changed files with 427 additions and 22 deletions.
40 changes: 40 additions & 0 deletions cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { parseArgs } from "https://deno.land/std@0.209.0/cli/mod.ts";

const { _, ...args } = parseArgs(Deno.args, {
string: ["_", "out"],
alias: { "out": ["-o", "--out"] },
});

const [command, file, ...rest] = _;
const out = args.out ?? "compiled.rkt";

// commands: compile, check

switch (command) {
case "compile": {
const { tokenize, parse } = await import("./main.ts");
const { compile } = await import("./compile.ts");
const source = await Deno.readTextFile(file);
const tokens = tokenize(source);
const ast = parse(tokens);
const compiled = compile(ast);
await Deno.writeTextFile(out, compiled);
break;
}
case "check": {
const { tokenize, parse } = await import("./main.ts");
const { typecheck } = await import("./typecheck.ts");
const source = await Deno.readTextFile(file);
const tokens = tokenize(source);
const ast = parse(tokens);
const errors = typecheck(ast);
if (errors.length > 0) {
console.error(errors);
Deno.exit(1);
}
break;
}
default:
console.error(`Unknown command: ${command}`);
Deno.exit(1);
}
48 changes: 29 additions & 19 deletions compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,23 @@ type PartialCode = string;
export interface CompileOptions {
indent?: number | "tab";
}
function compile(ast: AST.Program, opts: CompileOptions = {

const typeToString = (type: AST.TypeAnnotation): string => {
if (type.type === "type-function") {
switch (type.name) {
case "List-of":
return `(Listof Any)`; // TODO
case "Any":
return "any";
}
} else if (type.type === "type-literal") {
return type.name.value;
} else {
throw new Error(`Unknown type: ${type}`);
}
};

export function compile(ast: AST.Program, opts: CompileOptions = {
indent: 2,
}): string {
const indent = opts.indent === "tab" ? "\t" : " ".repeat(opts.indent ?? 2);
Expand Down Expand Up @@ -111,6 +127,17 @@ function compile(ast: AST.Program, opts: CompileOptions = {
}
function compileDefineFunction(expr: AST.DefineFunction): PartialCode {
return partial([
`;; ${expr.name.value} : ${
expr.signature.parameters.map((param) => {
return expr.signature.type === "untyped-parameters"
? "any"
: typeToString(param.type as AST.TypeAnnotation);
}).join(" ")
} -> ${
expr.signature.type === "untyped-parameters"
? "any"
: typeToString(expr.signature.returnType)
}`,
"(define (" + compileIdentifier(expr.name) + " " +
compileFunctionSignature(expr.signature) + ")",
layer(compileFunctionValue(expr.body)) + ")",
Expand Down Expand Up @@ -243,22 +270,5 @@ function compile(ast: AST.Program, opts: CompileOptions = {
function compileSymbolValue(expr: AST.SymbolValue): string {
return expr.value;
}
return partials.join("\n");
return "#lang htdp/isl+\n" + partials.join("\n");
}

const code = `\
(define NAME "Joseph")
(define AGE 19)
(define (square x)
(* x x))
(define (sum-of-squares x : Number & y : Number -> Number)
(+ (square x) (square y)))
(define (func x)
(if (> x 0) (sum-of-squares x (* x 2)) 0))
(define (func2 x)
(local ((define (square x)
(* x x)))
(square x)))`;
const tokens = AST.tokenize(code);
const ast = AST.parse(tokens);
console.log(compile(ast));
30 changes: 30 additions & 0 deletions compiled.rkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#lang htdp/isl+
;; k : Number Number -> Number
(define (k x y)
"")
;; v : String -> Number
(define (v u)
(string->number
u
))
(+
(k
1
2
)
(v
""
)
)
(+
(v
1
)
(k
2
)
)
(k
3
""
)
7 changes: 6 additions & 1 deletion deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions example.trkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

(define (k x : Number & y : Number -> Number)
"")
(define (v u : String -> Number)
(string->number u))
(+ (k 1 2) (v "3"))
;; wrong example
(+ (v 1) (k 2))
(k 3 "4")
19 changes: 17 additions & 2 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ TypeLiteral -> Identifier
UntypedParameters -> Identifier+
DefineStruct -> "define-struct" Identifier "(" Parameters ")"
DefineStruct -> "define-struct" Identifier "(" Parameters ")"
Function -> IfStatement
| CondStatement
Expand Down Expand Up @@ -633,6 +633,21 @@ export type SymbolValue = {
value: string;
};

export type WithLoc<T> = T & {
position: {
start: {
line: number;
column: number;
index: number;
};
end: {
line: number;
column: number;
index: number;
};
};
};

export function parse(tokens: Token[]) {
let current = 0;

Expand Down Expand Up @@ -669,7 +684,7 @@ export function parse(tokens: Token[]) {
}
function checkNext(type: Token["type"]) {
if (isAtEnd()) return false;
return peekNext().type === type;
return peekNext()?.type === type;
}

function program() {
Expand Down
Loading

0 comments on commit b34eeb7

Please sign in to comment.