Skip to content

Commit

Permalink
const variables
Browse files Browse the repository at this point in the history
  • Loading branch information
DvvCz committed Sep 2, 2023
1 parent 165fe4c commit 196ec2d
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 19 deletions.
31 changes: 15 additions & 16 deletions packages/ramattra-core/src/compiler/analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type IRExprData =
export type IREvent =
["event", string, string, IRStmt];

type Scope = { kind?: null | "loop" | "function", variables: Map<string, IRExpr> };
type Scope = { kind?: null | "loop" | "function", variables: Map<string, { const: boolean, expr: IRExpr }> };

function error(e: Node<any>, message: string): never {
throw {
Expand Down Expand Up @@ -77,7 +77,7 @@ export function analyze(src: string): IREvent[] {
const lookupKind = (kind: Scope["kind"]): boolean =>
scopes.find(i => i.kind == kind) !== undefined;

const lookupVariable = (name: string): IRExpr | undefined => {
const lookupVariable = (name: string): { const: boolean, expr: IRExpr } | undefined => {

for (let i = scopes.length - 1; i >= 0; i--) {
const scope = scopes[i];
Expand All @@ -89,7 +89,7 @@ export function analyze(src: string): IREvent[] {

const constant = CONSTANTS[name];
if (constant)
return { type: constant.type, data: ["constant", constant.ow] }
return { const: true, expr: { type: constant.type, data: ["constant", constant.ow] } }
}

const analyzeExpr = (expr: Expr, stmts: IRStmt[]): IRExpr => {
Expand Down Expand Up @@ -175,11 +175,11 @@ export function analyze(src: string): IREvent[] {
error(expr, `No such function ${name}`);


stmts.push(analyzeStmt(sugar(expr, ["let", "__returnval__", ufn.ret, null]), stmts));
stmts.push(analyzeStmt(sugar(expr, ["let", "__returnval__", ufn.ret, null, false]), stmts));

const inner = sugar(expr, ["block", [
...ufn.args.map((arg, i) =>
sugar(expr, ["let", arg.name, arg.type, args[i]])
sugar(expr, ["let", arg.name, arg.type, args[i], true])
),
...ufn.block.data[1] as Stmt[]
], "function"]);
Expand Down Expand Up @@ -215,7 +215,7 @@ export function analyze(src: string): IREvent[] {
const v = lookupVariable(expr.data[1]);
if (!v)
error(expr, `Variable ${expr.data[1]} is not defined.`);
return v;
return v.expr;
}

return kind;
Expand All @@ -242,10 +242,9 @@ export function analyze(src: string): IREvent[] {
} else if (kind == "while") {
const [, exp, block] = statement.data;
block.data[2] = "loop";
console.log("whl", block.data[2]);
return ["while", analyzeExpr(exp, stmts), analyzeStmt(block, stmts)];
} else if (kind == "let") {
const [name, expr] = [statement.data[1], statement.data[3] && analyzeExpr(statement.data[3], stmts)];
const [name, expr, immutable] = [statement.data[1], statement.data[3] && analyzeExpr(statement.data[3], stmts), statement.data[4]];
const type = statement.data[2] || expr?.type;

if (!type)
Expand All @@ -264,7 +263,7 @@ export function analyze(src: string): IREvent[] {
if (!interner.has(str))
interner.set(str, id);

scope.variables.set(name, { type: type, data: ["ident", id] });
scope.variables.set(name, { const: immutable, expr: { type: type, data: ["ident", id] } });

if (expr) {
return ["let", id, type, expr];
Expand All @@ -278,13 +277,13 @@ export function analyze(src: string): IREvent[] {
if (!v)
error(statement, `Variable ${name} has not been declared. Maybe you meant let ${name}?`);

if (!solver.satisfies(v.type, expr.type))
error(statement, `Cannot assign value of ${reprType(expr.type)} to variable of type ${reprType(v.type)}`);
if (!solver.satisfies(v.expr.type, expr.type))
error(statement, `Cannot assign value of ${reprType(expr.type)} to variable of type ${reprType(v.expr.type)}`);

if (v.data[0] == "constant")
if (v.const)
error(statement, `Cannot assign to constant ${name}`);

return ["assign", v.data[1] as number, expr];
return ["assign", v.expr.data[1] as number, expr];
} else if (kind == "call") {
const [name, args] = [statement.data[1], statement.data[2]];

Expand Down Expand Up @@ -316,9 +315,9 @@ export function analyze(src: string): IREvent[] {
error(statement, `No such function ${name}`);

const desugared: Stmt[] = [
sugar(statement, ["let", "__returnval__", ufn.ret, null]),
sugar(statement, ["let", "__returnval__", ufn.ret, null, false]),
...ufn.args.map((arg, i) =>
sugar(statement, ["let", arg.name, arg.type, args[i]])
sugar(statement, ["let", arg.name, arg.type, args[i], true])
),
...ufn.block.data[1] as Stmt[]
];
Expand Down Expand Up @@ -377,7 +376,7 @@ export function analyze(src: string): IREvent[] {
scope = { variables: new Map() };
for (const [i, arg] of args.entries()) {
const registered = event.args[i];
scope.variables.set(arg, { type: registered.type, data: ["constant", registered.ow] });
scope.variables.set(arg, { const: true, expr: { type: registered.type, data: ["constant", registered.ow] } });
}

scopes.push(scope);
Expand Down
7 changes: 4 additions & 3 deletions packages/ramattra-core/src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Stmt =
"if" _ cond:Expr _ block:Block { return wrap(location(), ["if", cond, block]) }
/ "for" _ marker:ident _ "in" _ start:Expr _ ".." _ end:Expr _ block:Block {
return wrap(location(), ["block", [
wrap(location(), ["let", marker, { kind: "native", name: "number" }, start]),
wrap(location(), ["let", marker, { kind: "native", name: "number" }, start, false]),
wrap(location(), ["while", wrap(location(), ["<", wrap(location(), ["ident", marker]), end]),
wrap(location(), ["block", [
block,
Expand All @@ -48,7 +48,8 @@ Stmt =
]])
}
/ "while" _ cond:Expr _ block:Block { return wrap(location(), ["while", cond, block]) }
/ "let" _ name:ident _ type:(":" _ @Type)? _ value:("=" _ @Expr)? { return wrap(location(), ["let", name, type, value]) }
/ "let" _ name:ident _ type:(":" _ @Type)? _ value:("=" _ @Expr)? { return wrap(location(), ["let", name, type, value, false]) }
/ "const" _ name:ident _ type:(":" _ @Type)? _ value:("=" _ @Expr)? { return wrap(location(), ["let", name, type, value, true]) }
/ "return" _ exp:Expr? { return wrap(location(), ["return", exp]) }
/ action:("continue" / "break") { return wrap(location(), [action]) }
/ name:ident _ op:("+" / "-" / "*" / "/") "=" _ value:Expr { return wrap(location(), ["assign", name, wrap(location(), [op, wrap(location(), ["ident", name]), value])]) }
Expand Down Expand Up @@ -135,7 +136,7 @@ export type StmtData =
["block", Stmt[], null | "loop" | "function"]
| ["if", Expr, Stmt]
| ["while", Expr, Stmt]
| ["let", string, Type, Expr | null]
| ["let", string, Type, Expr | null, boolean]
| ["assign", string, Expr]
| ["iassign", Expr, string, Expr]
| ["call", string, Expr[]]
Expand Down

0 comments on commit 196ec2d

Please sign in to comment.