Skip to content

Commit

Permalink
OUTPUT anything
Browse files Browse the repository at this point in the history
  • Loading branch information
BalaM314 committed Jul 16, 2024
1 parent 41d5d21 commit 71474f9
Show file tree
Hide file tree
Showing 9 changed files with 1,321 additions and 58 deletions.
2 changes: 1 addition & 1 deletion build/lexer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export declare const tokenNameTypeData: {
readonly ".": "punctuation.period";
readonly "\n": "newline";
};
export declare const tokenTextMapping: Record<"brace.open" | "brace.close" | "bracket.open" | "bracket.close" | "parentheses.open" | "parentheses.close" | "punctuation.colon" | "punctuation.semicolon" | "punctuation.comma" | "punctuation.period" | "boolean.true" | "boolean.false" | "keyword.declare" | "keyword.define" | "keyword.constant" | "keyword.output" | "keyword.input" | "keyword.call" | "keyword.if" | "keyword.then" | "keyword.else" | "keyword.if_end" | "keyword.for" | "keyword.to" | "keyword.for_end" | "keyword.step" | "keyword.while" | "keyword.while_end" | "keyword.dowhile" | "keyword.dowhile_end" | "keyword.function" | "keyword.function_end" | "keyword.procedure" | "keyword.procedure_end" | "keyword.return" | "keyword.returns" | "keyword.pass_mode.by_reference" | "keyword.pass_mode.by_value" | "keyword.type" | "keyword.type_end" | "keyword.open_file" | "keyword.read_file" | "keyword.write_file" | "keyword.close_file" | "keyword.get_record" | "keyword.put_record" | "keyword.seek" | "keyword.file_mode.read" | "keyword.file_mode.write" | "keyword.file_mode.append" | "keyword.file_mode.random" | "keyword.case" | "keyword.of" | "keyword.case_end" | "keyword.otherwise" | "keyword.class" | "keyword.class_end" | "keyword.new" | "keyword.super" | "keyword.inherits" | "keyword.class_modifier.private" | "keyword.class_modifier.public" | "keyword.array" | "keyword.set" | "newline" | "operator.add" | "operator.minus" | "operator.multiply" | "operator.divide" | "operator.mod" | "operator.integer_divide" | "operator.and" | "operator.or" | "operator.not" | "operator.equal_to" | "operator.not_equal_to" | "operator.less_than" | "operator.greater_than" | "operator.less_than_equal" | "operator.greater_than_equal" | "operator.assignment" | "operator.pointer" | "operator.string_concatenate", "." | "AND" | "APPEND" | "ARRAY" | "BYREF" | "BYVAL" | "CALL" | "CASE" | "CLASS" | "CLOSEFILE" | "CONSTANT" | "DECLARE" | "DEFINE" | "DIV" | "ELSE" | "ENDCASE" | "ENDCLASS" | "ENDFUNCTION" | "ENDIF" | "ENDPROCEDURE" | "ENDTYPE" | "ENDWHILE" | "FALSE" | "FOR" | "FUNCTION" | "GETRECORD" | "IF" | "INHERITS" | "INPUT" | "MOD" | "NEW" | "NEXT" | "NOT" | "OF" | "OPENFILE" | "OR" | "OTHERWISE" | "OUTPUT" | "PRIVATE" | "PROCEDURE" | "PUBLIC" | "PUTRECORD" | "RANDOM" | "READ" | "READFILE" | "REPEAT" | "RETURN" | "RETURNS" | "SEEK" | "SET" | "STEP" | "SUPER" | "THEN" | "TO" | "TRUE" | "TYPE" | "UNTIL" | "WHILE" | "WRITE" | "WRITEFILE" | "<-" | ">=" | "<=" | "<>" | "=" | ">" | "<" | "+" | "-" | "*" | "/" | "^" | "&" | "(" | ")" | "[" | "]" | "{" | "}" | ":" | ";" | "," | "\n">;
export declare const tokenTextMapping: Record<"brace.open" | "brace.close" | "bracket.open" | "bracket.close" | "parentheses.open" | "parentheses.close" | "punctuation.colon" | "punctuation.semicolon" | "punctuation.comma" | "punctuation.period" | "newline" | "operator.add" | "operator.minus" | "operator.multiply" | "operator.divide" | "operator.mod" | "operator.integer_divide" | "operator.and" | "operator.or" | "operator.not" | "operator.equal_to" | "operator.not_equal_to" | "operator.less_than" | "operator.greater_than" | "operator.less_than_equal" | "operator.greater_than_equal" | "operator.assignment" | "operator.pointer" | "operator.string_concatenate" | "boolean.true" | "boolean.false" | "keyword.declare" | "keyword.define" | "keyword.constant" | "keyword.output" | "keyword.input" | "keyword.call" | "keyword.if" | "keyword.then" | "keyword.else" | "keyword.if_end" | "keyword.for" | "keyword.to" | "keyword.for_end" | "keyword.step" | "keyword.while" | "keyword.while_end" | "keyword.dowhile" | "keyword.dowhile_end" | "keyword.function" | "keyword.function_end" | "keyword.procedure" | "keyword.procedure_end" | "keyword.return" | "keyword.returns" | "keyword.pass_mode.by_reference" | "keyword.pass_mode.by_value" | "keyword.type" | "keyword.type_end" | "keyword.open_file" | "keyword.read_file" | "keyword.write_file" | "keyword.close_file" | "keyword.get_record" | "keyword.put_record" | "keyword.seek" | "keyword.file_mode.read" | "keyword.file_mode.write" | "keyword.file_mode.append" | "keyword.file_mode.random" | "keyword.case" | "keyword.of" | "keyword.case_end" | "keyword.otherwise" | "keyword.class" | "keyword.class_end" | "keyword.new" | "keyword.super" | "keyword.inherits" | "keyword.class_modifier.private" | "keyword.class_modifier.public" | "keyword.array" | "keyword.set", "\n" | ">=" | "<=" | "<>" | "=" | ">" | "<" | "+" | "-" | "*" | "/" | "^" | "&" | "(" | ")" | "[" | "]" | "{" | "}" | ":" | ";" | "," | "." | "AND" | "APPEND" | "ARRAY" | "BYREF" | "BYVAL" | "CALL" | "CASE" | "CLASS" | "CLOSEFILE" | "CONSTANT" | "DECLARE" | "DEFINE" | "DIV" | "ELSE" | "ENDCASE" | "ENDCLASS" | "ENDFUNCTION" | "ENDIF" | "ENDPROCEDURE" | "ENDTYPE" | "ENDWHILE" | "FALSE" | "FOR" | "FUNCTION" | "GETRECORD" | "IF" | "INHERITS" | "INPUT" | "MOD" | "NEW" | "NEXT" | "NOT" | "OF" | "OPENFILE" | "OR" | "OTHERWISE" | "OUTPUT" | "PRIVATE" | "PROCEDURE" | "PUBLIC" | "PUTRECORD" | "RANDOM" | "READ" | "READFILE" | "REPEAT" | "RETURN" | "RETURNS" | "SEEK" | "SET" | "STEP" | "SUPER" | "THEN" | "TO" | "TRUE" | "TYPE" | "UNTIL" | "WHILE" | "WRITE" | "WRITEFILE" | "<-">;
type SymbolSpecifierFuncName = "isAlphanumeric" | "isNumber";
export declare function symbolize(input: string): SymbolizedProgram;
export declare function tokenize(input: SymbolizedProgram): TokenizedProgram;
Expand Down
2 changes: 1 addition & 1 deletion build/parser-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export declare class Operator implements IFormattable {
fmtDebug(): string;
}
export declare const operatorsByPriority: Operator[][];
export declare const operators: Omit<Record<"assignment" | "negate" | "subtract" | "access" | "pointer_reference" | "pointer_dereference" | "or" | "and" | "add" | "multiply" | "divide" | "mod" | "not" | "integer_divide" | "equal_to" | "not_equal_to" | "less_than" | "greater_than" | "less_than_equal" | "greater_than_equal" | "pointer" | "string_concatenate", Operator>, "assignment" | "pointer">;
export declare const operators: Omit<Record<"assignment" | "add" | "negate" | "subtract" | "access" | "pointer_reference" | "pointer_dereference" | "multiply" | "divide" | "mod" | "integer_divide" | "and" | "or" | "not" | "equal_to" | "not_equal_to" | "less_than" | "greater_than" | "less_than_equal" | "greater_than_equal" | "pointer" | "string_concatenate", Operator>, "assignment" | "pointer">;
export type TokenMatcher = TokenType | "." | "literal" | "literal|otherwise" | ".*" | ".+" | "expr+" | "type+" | "file_mode" | "class_modifier";
export type ProgramAST = {
program: string;
Expand Down
44 changes: 39 additions & 5 deletions build/runtime-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import type { Runtime } from "./runtime.js";
import type { AssignmentStatement, BuiltinFunctionArguments, ClassPropertyStatement, ClassStatement, ConstantStatement, DeclareStatement, DefineStatement, ForStatement, FunctionStatement, ProcedureStatement, Statement } from "./statements.js";
import { ClassFunctionStatement, ClassProcedureStatement } from "./statements.js";
import type { BoxPrimitive, IFormattable, RangeAttached, TextRange } from "./types.js";
export type VariableTypeMapping<T> = T extends PrimitiveVariableType<infer U> ? (U extends "INTEGER" ? number : U extends "REAL" ? number : U extends "STRING" ? string : U extends "CHAR" ? string : U extends "BOOLEAN" ? boolean : U extends "DATE" ? Date : never) : T extends ArrayVariableType ? Array<VariableTypeMapping<ArrayElementVariableType> | null> : T extends RecordVariableType ? {
export type VariableTypeMapping<T> = T extends PrimitiveVariableType<infer U> ? (U extends "INTEGER" ? number : U extends "REAL" ? number : U extends "STRING" ? string : U extends "CHAR" ? string : U extends "BOOLEAN" ? boolean : U extends "DATE" ? Date : never) : T extends ArrayVariableType ? Array<(number | string | boolean | Date | {
[index: string]: VariableTypeMapping<any> | null;
} | VariableData | ConstantData | string | (number | string | boolean | Date)[] | {
properties: {
[index: string]: VariableTypeMapping<any> | null;
};
propertyTypes: Record<string, VariableType>;
type: ClassVariableType;
}) | null> : T extends RecordVariableType ? {
[index: string]: VariableTypeMapping<any> | null;
} : T extends PointerVariableType ? VariableData<T["target"]> | ConstantData<T["target"]> : T extends EnumeratedVariableType ? string : T extends SetVariableType ? Array<VariableTypeMapping<PrimitiveVariableType>> : T extends ClassVariableType ? {
properties: {
Expand All @@ -21,6 +29,7 @@ export declare abstract class BaseVariableType implements IFormattable {
abstract fmtDebug(): string;
fmtQuoted(): string;
abstract fmtText(): string;
abstract asString(value: VariableValue): string;
}
export type PrimitiveVariableTypeName = "INTEGER" | "REAL" | "STRING" | "CHAR" | "BOOLEAN" | "DATE";
export type PrimitiveVariableType_<T extends PrimitiveVariableTypeName = PrimitiveVariableTypeName> = T extends string ? PrimitiveVariableType<T> : never;
Expand All @@ -44,6 +53,7 @@ export declare class PrimitiveVariableType<T extends PrimitiveVariableTypeName =
static get(type: string): PrimitiveVariableType | undefined;
static resolve(token: Token): Exclude<UnresolvedVariableType, ArrayVariableType>;
getInitValue(runtime: Runtime, requireInit: boolean): number | string | boolean | Date | null;
asString(value: VariableValue): string;
}
export declare class ArrayVariableType<Init extends boolean = true> extends BaseVariableType {
lengthInformationExprs: [low: ExpressionAST, high: ExpressionAST][] | null;
Expand All @@ -61,6 +71,7 @@ export declare class ArrayVariableType<Init extends boolean = true> extends Base
fmtDebug(): string;
getInitValue(runtime: Runtime, requireInit: boolean): VariableTypeMapping<ArrayVariableType>;
static from(node: ExpressionASTArrayTypeNode): ArrayVariableType<false>;
asString(value: VariableValue): string;
}
export declare class RecordVariableType<Init extends boolean = true> extends BaseVariableType {
initialized: Init;
Expand All @@ -76,6 +87,7 @@ export declare class RecordVariableType<Init extends boolean = true> extends Bas
fmtQuoted(): string;
fmtDebug(): string;
getInitValue(runtime: Runtime, requireInit: boolean): VariableValue | null;
asString(value: VariableValue): string;
}
export declare class PointerVariableType<Init extends boolean = true> extends BaseVariableType {
initialized: Init;
Expand All @@ -88,6 +100,7 @@ export declare class PointerVariableType<Init extends boolean = true> extends Ba
fmtQuoted(): string;
fmtDebug(): string;
getInitValue(runtime: Runtime): VariableValue | null;
asString(value: VariableValue): string;
}
export declare class EnumeratedVariableType extends BaseVariableType {
name: string;
Expand All @@ -99,6 +112,7 @@ export declare class EnumeratedVariableType extends BaseVariableType {
fmtQuoted(): string;
fmtDebug(): string;
getInitValue(runtime: Runtime): VariableValue | null;
asString(value: VariableValue): string;
}
export declare class SetVariableType<Init extends boolean = true> extends BaseVariableType {
initialized: Init;
Expand All @@ -111,6 +125,7 @@ export declare class SetVariableType<Init extends boolean = true> extends BaseVa
toQuotedString(): string;
fmtDebug(): string;
getInitValue(runtime: Runtime): VariableValue | null;
asString(value: VariableValue): string;
}
export declare class ClassVariableType<Init extends boolean = true> extends BaseVariableType {
initialized: Init;
Expand All @@ -135,23 +150,42 @@ export declare class ClassVariableType<Init extends boolean = true> extends Base
construct(runtime: Runtime, args: RangeArray<ExpressionASTNode>): {
properties: {
[index: string]: string | number | boolean | Date | (string | number | boolean | Date | {
[index: string]: string | number | boolean | Date | (string | number | boolean | Date | any | VariableData<VariableType, null> | ConstantData<VariableType> | null)[] | any | VariableData<any, null> | ConstantData<any> | (string | number | boolean | Date)[] | any | null;
} | VariableData<VariableType, null> | ConstantData<VariableType> | null)[] | {
[index: string]: string | number | boolean | Date | (string | number | boolean | Date | any | VariableData<VariableType, null> | ConstantData<VariableType> | null)[] | any | VariableData<any, null> | ConstantData<any> | (string | number | boolean | Date)[] | any | null;
[index: string]: string | number | boolean | Date | (string | number | boolean | Date | any | VariableData<VariableType, null> | ConstantData<VariableType> | (string | number | boolean | Date)[] | {
properties: {
[index: string]: string | number | boolean | Date | (string | number | boolean | Date | any | VariableData<VariableType, null> | ConstantData<VariableType> | (string | number | boolean | Date)[] | any | null)[] | {
[index: string]: string | number | boolean | Date | (string | number | boolean | Date | any | VariableData<VariableType, null> | ConstantData<VariableType> | (string | number | boolean | Date)[] | any | null)[] | any | VariableData<any, null> | ConstantData<any> | (string | number | boolean | Date)[] | any | null;
} | VariableData<any, null> | ConstantData<any> | (string | number | boolean | Date)[] | any | null;
};
propertyTypes: Record<string, VariableType>;
type: ClassVariableType<true>;
} | null)[] | {
[index: string]: string | number | boolean | Date | (string | number | boolean | Date | any | VariableData<VariableType, null> | ConstantData<VariableType> | (string | number | boolean | Date)[] | any | null)[] | any | VariableData<any, null> | ConstantData<any> | (string | number | boolean | Date)[] | any | null;
} | VariableData<any, null> | ConstantData<any> | (string | number | boolean | Date)[] | any | null;
} | VariableData<VariableType, null> | ConstantData<VariableType> | (string | number | boolean | Date)[] | {
properties: {
[index: string]: string | number | boolean | Date | (string | number | boolean | Date | any | VariableData<VariableType, null> | ConstantData<VariableType> | (string | number | boolean | Date)[] | any | null)[] | {
[index: string]: string | number | boolean | Date | (string | number | boolean | Date | any | VariableData<VariableType, null> | ConstantData<VariableType> | (string | number | boolean | Date)[] | any | null)[] | any | VariableData<any, null> | ConstantData<any> | (string | number | boolean | Date)[] | any | null;
} | VariableData<any, null> | ConstantData<any> | (string | number | boolean | Date)[] | any | null;
};
propertyTypes: Record<string, VariableType>;
type: ClassVariableType<true>;
} | null)[] | {
[index: string]: string | number | boolean | Date | (string | number | boolean | Date | any | VariableData<VariableType, null> | ConstantData<VariableType> | (string | number | boolean | Date)[] | any | null)[] | any | VariableData<any, null> | ConstantData<any> | (string | number | boolean | Date)[] | any | null;
} | VariableData<any, null> | ConstantData<any> | (string | number | boolean | Date)[] | any | null;
};
propertyTypes: Record<string, VariableType>;
type: ClassVariableType<true>;
};
getScope(runtime: Runtime, instance: VariableTypeMapping<ClassVariableType>): VariableScope;
asString(value: VariableValue): string;
}
export declare function typesEqual(a: VariableType | UnresolvedVariableType, b: VariableType | UnresolvedVariableType, types?: [VariableType, VariableType][]): boolean;
export declare function typesAssignable(base: VariableType, ext: VariableType): true | string;
export declare function typesAssignable(base: UnresolvedVariableType, ext: UnresolvedVariableType): true | string;
export declare const checkClassMethodsCompatible: (runtime: Runtime, base: ClassMethodStatement, derived: ClassMethodStatement) => void;
export type UnresolvedVariableType = PrimitiveVariableType | ArrayVariableType<false> | ["unresolved", name: string, range: TextRange];
export type VariableType = PrimitiveVariableType<"INTEGER"> | PrimitiveVariableType<"REAL"> | PrimitiveVariableType<"STRING"> | PrimitiveVariableType<"CHAR"> | PrimitiveVariableType<"BOOLEAN"> | PrimitiveVariableType<"DATE"> | PrimitiveVariableType | ArrayVariableType | RecordVariableType | PointerVariableType | EnumeratedVariableType | SetVariableType | ClassVariableType;
export type ArrayElementVariableType = PrimitiveVariableType | RecordVariableType | PointerVariableType | EnumeratedVariableType;
export type ArrayElementVariableType = PrimitiveVariableType | RecordVariableType | PointerVariableType | EnumeratedVariableType | ClassVariableType;
export type VariableValue = VariableTypeMapping<any>;
export declare const fileModes: readonly ["READ", "WRITE", "APPEND", "RANDOM"];
export type FileMode = typeof fileModes extends ReadonlyArray<infer T> ? T : never;
Expand Down
32 changes: 32 additions & 0 deletions build/runtime-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ export class PrimitiveVariableType extends BaseVariableType {
else
return null;
}
asString(value) {
switch (this.name) {
case "CHAR":
case "STRING":
case "INTEGER":
case "REAL":
return value.toString();
case "BOOLEAN":
return value.toString().toUpperCase();
case "DATE":
return value.toLocaleDateString("en-GB");
default: impossible();
}
}
}
PrimitiveVariableType.all = [];
PrimitiveVariableType.INTEGER = new PrimitiveVariableType("INTEGER");
Expand Down Expand Up @@ -120,6 +134,9 @@ export class ArrayVariableType extends BaseVariableType {
static from(node) {
return new ArrayVariableType(node.lengthInformation, node.lengthInformation ? getTotalRange(node.lengthInformation.flat()) : null, PrimitiveVariableType.resolve(node.elementType), node.range);
}
asString(value) {
return `[${value.map(v => this.elementType.asString(v)).join(", ")}]`;
}
}
export class RecordVariableType extends BaseVariableType {
constructor(initialized, name, fields) {
Expand Down Expand Up @@ -176,6 +193,9 @@ export class RecordVariableType extends BaseVariableType {
return Object.fromEntries(Object.entries(this.fields)
.map(([k, [v, r]]) => [k, v.getInitValue(runtime, false)]));
}
asString(value) {
fail(`Outputting record type instances is not yet implemented`, undefined);
}
}
export class PointerVariableType extends BaseVariableType {
constructor(initialized, name, target) {
Expand Down Expand Up @@ -204,6 +224,9 @@ export class PointerVariableType extends BaseVariableType {
getInitValue(runtime) {
return null;
}
asString(value) {
return "pointer";
}
}
export class EnumeratedVariableType extends BaseVariableType {
constructor(name, values) {
Expand All @@ -227,6 +250,9 @@ export class EnumeratedVariableType extends BaseVariableType {
getInitValue(runtime) {
return null;
}
asString(value) {
return value;
}
}
export class SetVariableType extends BaseVariableType {
constructor(initialized, name, baseType) {
Expand Down Expand Up @@ -255,6 +281,9 @@ export class SetVariableType extends BaseVariableType {
getInitValue(runtime) {
crash(`Cannot initialize a variable of type SET`);
}
asString(value) {
return `[${value.map(v => this.baseType.asString(v)).join(", ")}]`;
}
}
export class ClassVariableType extends BaseVariableType {
constructor(initialized, statement, properties = {}, ownMethods = {}, allMethods = {}, propertyStatements = []) {
Expand Down Expand Up @@ -372,6 +401,9 @@ export class ClassVariableType extends BaseVariableType {
}]))
};
}
asString(value) {
return `${this.name} { NOT_YET_IMPLEMENTED }`;
}
}
export function typesEqual(a, b, types = new Array()) {
return a == b ||
Expand Down
Loading

0 comments on commit 71474f9

Please sign in to comment.