Intérpretes

Temas:

  1. TODO
  2. TODO
  3. TODO

Bibliografía:

  1. Mogensen, T. Æ. (2011). Introduction to compiler design. Springer. http://www.diku.dk/ torbenm/Basics.
  2. https://craftinginterpreters.com/

Tour por jsonlang


					export type Statement<Expr> = 
						| {
							if: { cond: Expr; then: Statement<Expr> }[];
							else?: Statement<Expr>;
						}
						| { while: Expr; do: Statement<Expr> }
						| Statement<Expr>[]
						| { iterator: string; from: Expr; to: Expr; step?: Expr; do: Statement<Expr> }
						| { do: Statement<Expr>; until: Expr }
						| "break"
						| "continue"
						| { declare: string; value: Expr }
						| { set: string; value: Expr }
						| { call: string; args: Expr[] }
						| { return: Expr }
					
					
					type Binops =
						| "+"
						| "-"
						| "*"
						| "/"
						| "^"
						| "%"
						| "&"
						| "|"
						| ">>"
						| "<<"
						| "<"
						| "<="
						| ">"
						| ">="
						| "=="
						| "~="
						| "and"
						| "or";
					
					export type Expression =
						| { unop: "-" | "!" | "~"; arg: Expression }
						| { binop: Binops; argl: Expression; argr: Expression }
						| string
						| { call: string; args: Expression[] }
						| number;
					
					export type DeclarationStatement<Stmt>={
						function: string;
						args: string[];
						block: Stmt;
					};
					
					export type TopStatement<Expr> = Statement<Expr> | DeclarationStatement<Statement<Expr>>
					
					export type JsonLang = TopStatement<Expression>[];
					
				

Scopes

Operaciones de un diccionario

  • Crear vacío
  • set
  • look up

Operaciones de un contexto lexical scope (Mogensen, 4.2):

  • Crear vacío
  • bind
  • look up
  • enter
  • exit

Implementación posible: pila de diccionarios

Operaciones de un contexto nuestro:

  • Crear vacío
  • inicializar
  • asignar
  • look up
  • enter
  • exit
  • entrar a función
  • salir de función

Implementación posible: pila de pilas de diccionarios


							export interface IContext {
								exitFunction(): void;
								enterFunction(): void;
								set(n: string, v: number): void;
								declare(n: string, v: number): void;
								exitBlock(): void;
								enterBlock(): void;
								get(n: string): number;
							}
						

Modelar flujo


import { Executor } from "./Executor.ts";
import { IContext } from "../interfaces/IContext.ts";
import { IEvaluator } from "../interfaces/IEvaluator.ts";

export type FlowSignals = "breakSignal" | "continueSignal" | null;

export type FlowStatement =
    | {
            if: { cond: Expr; then: Stmt }[];
            else?: Stmt;
        }
    | { while: Expr; do: Stmt }
    | Stmt[]
    | { iterator: string; from: Expr; to: Expr; step?: Expr; do: Stmt }
    | { do: Stmt; until: Expr }
    | "break"
    | "continue";

export class FlowExecutor extends Executor<
    FlowStatement,
    Stmt,
    FlowSignals,
    Sign | FlowSignals
> {
    constructor(private evaluator: IEvaluator, private context: IContext) {
        super();
    }

    execute(stmt: FlowStatement | Stmt): FlowSignals | Sign {
        if (stmt === "break") {
            return "breakSignal";
        }
        if (stmt === "continue") {
            return "continueSignal";
        }
        if (typeof stmt === "object" && stmt != null && "if" in stmt) {
            for (const clause of stmt.if) {
                const { cond, then } = clause;
                if (this.evaluator.evaluate(cond)) {
                    return this.executeNext(then);
                }
            }
            if ("else" in stmt && stmt.else) {
                return this.executeNext(stmt.else);
            }
        }
        throw new Error("Not implemented");
    }
}