Fix some compilation errors
This commit is contained in:
parent
98ddad8562
commit
831ae626c3
4 changed files with 115 additions and 74 deletions
25
spec/ast.txt
25
spec/ast.txt
|
@ -84,10 +84,6 @@ node BoltQualName {
|
||||||
name: BoltSymbol,
|
name: BoltSymbol,
|
||||||
}
|
}
|
||||||
|
|
||||||
node BoltSentence > BoltSourceElement {
|
|
||||||
tokens: Vec<BoltToken>,
|
|
||||||
}
|
|
||||||
|
|
||||||
node BoltTypeExpression;
|
node BoltTypeExpression;
|
||||||
|
|
||||||
node BoltReferenceTypeExpression > BoltTypeExpression {
|
node BoltReferenceTypeExpression > BoltTypeExpression {
|
||||||
|
@ -177,7 +173,7 @@ node BoltConstantExpression > BoltExpression {
|
||||||
value: BoltValue,
|
value: BoltValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
node BoltStatement > BoltSourceElement;
|
node BoltStatement > BoltFunctionBodyElement, BoltSourceElement;
|
||||||
|
|
||||||
node BoltReturnStatement > BoltStatement {
|
node BoltReturnStatement > BoltStatement {
|
||||||
value: Option<BoltExpression>,
|
value: Option<BoltExpression>,
|
||||||
|
@ -213,16 +209,18 @@ node BoltModule > BoltDeclaration {
|
||||||
elements: Vec<BoltSourceElement>,
|
elements: Vec<BoltSourceElement>,
|
||||||
}
|
}
|
||||||
|
|
||||||
node BoltFunctionDeclaration > BoltDeclaration {
|
node BoltFunctionBodyElement;
|
||||||
|
|
||||||
|
node BoltFunctionDeclaration > BoltFunctionBodyElement, BoltDeclaration {
|
||||||
modifiers: BoltDeclarationModifiers,
|
modifiers: BoltDeclarationModifiers,
|
||||||
target: String,
|
target: String,
|
||||||
name: BoltSymbol,
|
name: BoltSymbol,
|
||||||
params: Vec<BoltParameter>,
|
params: Vec<BoltParameter>,
|
||||||
returnType: Option<BoltTypeExpression>,
|
returnType: Option<BoltTypeExpression>,
|
||||||
body: Vec<BoltStatement>,
|
body: Vec<BoltFunctionBodyElement>,
|
||||||
}
|
}
|
||||||
|
|
||||||
node BoltVariableDeclaration > BoltDeclaration {
|
node BoltVariableDeclaration > BoltFunctionBodyElement, BoltDeclaration {
|
||||||
modifiers: BoltDeclarationModifiers,
|
modifiers: BoltDeclarationModifiers,
|
||||||
bindings: BoltPattern,
|
bindings: BoltPattern,
|
||||||
type: Option<BoltTypeExpression>,
|
type: Option<BoltTypeExpression>,
|
||||||
|
@ -262,7 +260,9 @@ node BoltTypeAliasDeclaration > BoltDeclaration {
|
||||||
typeExpr: BoltTypeExpression,
|
typeExpr: BoltTypeExpression,
|
||||||
}
|
}
|
||||||
|
|
||||||
node BoltRecordDeclarationField {
|
node BoltRecordMember;
|
||||||
|
|
||||||
|
node BoltRecordField > BoltRecordMember {
|
||||||
name: BoltIdentifier,
|
name: BoltIdentifier,
|
||||||
type: BoltTypeExpression,
|
type: BoltTypeExpression,
|
||||||
}
|
}
|
||||||
|
@ -271,11 +271,16 @@ node BoltRecordDeclaration > BoltDeclaration {
|
||||||
modifiers: BoltDeclarationModifiers,
|
modifiers: BoltDeclarationModifiers,
|
||||||
name: BoltQualName,
|
name: BoltQualName,
|
||||||
typeParms: Option<Vec<BoltTypeParameter>>,
|
typeParms: Option<Vec<BoltTypeParameter>>,
|
||||||
fields: Vec<BoltRecordDeclarationField>,
|
members: Option<Vec<BoltRecordMember>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
node BoltSourceElement;
|
node BoltSourceElement;
|
||||||
|
|
||||||
|
node BoltMacroCall > BoltRecordMember, BoltStatement, BoltDeclaration, BoltExpression {
|
||||||
|
name: BoltIdentifier,
|
||||||
|
text: String,
|
||||||
|
}
|
||||||
|
|
||||||
// JavaScript AST definitions
|
// JavaScript AST definitions
|
||||||
|
|
||||||
type JSValue = Int | String | Bool | Void;
|
type JSValue = Int | String | Bool | Void;
|
||||||
|
|
4
src/ast.d.ts
vendored
4
src/ast.d.ts
vendored
|
@ -583,7 +583,7 @@ export interface BoltFunctionDeclaration extends SyntaxBase<SyntaxKind.BoltFunct
|
||||||
name: BoltSymbol;
|
name: BoltSymbol;
|
||||||
params: BoltParameter[];
|
params: BoltParameter[];
|
||||||
returnType: BoltTypeExpression | null;
|
returnType: BoltTypeExpression | null;
|
||||||
body: BoltStatement[];
|
body: BoltFunctionBodyElement[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BoltVariableDeclaration extends SyntaxBase<SyntaxKind.BoltVariableDeclaration> {
|
export interface BoltVariableDeclaration extends SyntaxBase<SyntaxKind.BoltVariableDeclaration> {
|
||||||
|
@ -1403,7 +1403,7 @@ export function createBoltResumeStatement(value: BoltExpression, span?: TextSpan
|
||||||
export function createBoltExpressionStatement(expression: BoltExpression, span?: TextSpan | null): BoltExpressionStatement;
|
export function createBoltExpressionStatement(expression: BoltExpression, span?: TextSpan | null): BoltExpressionStatement;
|
||||||
export function createBoltParameter(index: number, bindings: BoltPattern, type: BoltTypeExpression | null, defaultValue: BoltExpression | null, span?: TextSpan | null): BoltParameter;
|
export function createBoltParameter(index: number, bindings: BoltPattern, type: BoltTypeExpression | null, defaultValue: BoltExpression | null, span?: TextSpan | null): BoltParameter;
|
||||||
export function createBoltModule(modifiers: BoltDeclarationModifiers, name: BoltQualName, elements: BoltSourceElement[], span?: TextSpan | null): BoltModule;
|
export function createBoltModule(modifiers: BoltDeclarationModifiers, name: BoltQualName, elements: BoltSourceElement[], span?: TextSpan | null): BoltModule;
|
||||||
export function createBoltFunctionDeclaration(modifiers: BoltDeclarationModifiers, target: string, name: BoltSymbol, params: BoltParameter[], returnType: BoltTypeExpression | null, body: BoltStatement[], span?: TextSpan | null): BoltFunctionDeclaration;
|
export function createBoltFunctionDeclaration(modifiers: BoltDeclarationModifiers, target: string, name: BoltSymbol, params: BoltParameter[], returnType: BoltTypeExpression | null, body: BoltFunctionBodyElement[], span?: TextSpan | null): BoltFunctionDeclaration;
|
||||||
export function createBoltVariableDeclaration(modifiers: BoltDeclarationModifiers, bindings: BoltPattern, type: BoltTypeExpression | null, value: BoltExpression | null, span?: TextSpan | null): BoltVariableDeclaration;
|
export function createBoltVariableDeclaration(modifiers: BoltDeclarationModifiers, bindings: BoltPattern, type: BoltTypeExpression | null, value: BoltExpression | null, span?: TextSpan | null): BoltVariableDeclaration;
|
||||||
export function createBoltPlainImportSymbol(name: BoltQualName, span?: TextSpan | null): BoltPlainImportSymbol;
|
export function createBoltPlainImportSymbol(name: BoltQualName, span?: TextSpan | null): BoltPlainImportSymbol;
|
||||||
export function createBoltImportDeclaration(file: string, symbols: BoltImportSymbol[], span?: TextSpan | null): BoltImportDeclaration;
|
export function createBoltImportDeclaration(file: string, symbols: BoltImportSymbol[], span?: TextSpan | null): BoltImportDeclaration;
|
||||||
|
|
126
src/checker.ts
126
src/checker.ts
|
@ -5,6 +5,8 @@ import {
|
||||||
SyntaxKind,
|
SyntaxKind,
|
||||||
BoltImportDeclaration,
|
BoltImportDeclaration,
|
||||||
BoltPattern,
|
BoltPattern,
|
||||||
|
isBoltTypeAliasDeclaration,
|
||||||
|
BoltFunctionBodyElement,
|
||||||
} from "./ast"
|
} from "./ast"
|
||||||
|
|
||||||
import { FastStringMap, getFullTextOfQualName } from "./util"
|
import { FastStringMap, getFullTextOfQualName } from "./util"
|
||||||
|
@ -45,13 +47,13 @@ export const noneType = new PrimType();
|
||||||
|
|
||||||
export class RecordType {
|
export class RecordType {
|
||||||
|
|
||||||
fieldTypes: FastStringMap<Type> = Object.create(null);
|
private fieldTypes = new FastStringMap<string, Type>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
iterable: IterableIterator<[string, Type]>,
|
iterable: IterableIterator<[string, Type]>,
|
||||||
) {
|
) {
|
||||||
for (const [name, typ] of iterable) {
|
for (const [name, type] of iterable) {
|
||||||
this.fieldTypes[name] = typ;
|
this.fieldTypes.set(name, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,18 +62,47 @@ export class RecordType {
|
||||||
}
|
}
|
||||||
|
|
||||||
getTypeOfField(name: string) {
|
getTypeOfField(name: string) {
|
||||||
if (name in this.fieldTypes) {
|
return this.fieldTypes.get(name);
|
||||||
return this.fieldTypes[name]
|
|
||||||
}
|
|
||||||
throw new Error(`Field '${name}' does not exist on this record type.`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SymbolInfo {
|
||||||
|
type: Type | null;
|
||||||
|
definitions: Syntax[];
|
||||||
|
}
|
||||||
|
|
||||||
export class Scope {
|
export class Scope {
|
||||||
|
|
||||||
constructor(public origin: Syntax) {
|
private symbolsByLocalName = new FastStringMap<string, SymbolInfo>();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public originatingNode: Syntax,
|
||||||
|
public parentScope?: Scope | null
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSymbolNamed(name: string): SymbolInfo | null {
|
||||||
|
let currScope: Scope | null = this;
|
||||||
|
while (true) {
|
||||||
|
if (currScope.symbolsByLocalName.has(name)) {
|
||||||
|
return currScope.symbolsByLocalName.get(name);
|
||||||
|
}
|
||||||
|
currScope = currScope.parentScope;
|
||||||
|
if (currScope === null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTypeNamed(name: string): Type | null {
|
||||||
|
const sym = this.getSymbolNamed(name);
|
||||||
|
if (sym === null || !introducesNewType(sym.definitions[0].kind)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return sym.type!;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -87,6 +118,16 @@ function* map<T, R>(iterable: Iterable<T>, proc: (value: T) => R): IterableItera
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function introducesNewType(kind: SyntaxKind): boolean {
|
||||||
|
return kind === SyntaxKind.BoltRecordDeclaration
|
||||||
|
|| kind === SyntaxKind.BoltTypeAliasDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
function introducesNewScope(kind: SyntaxKind): boolean {
|
||||||
|
return kind === SyntaxKind.BoltFunctionDeclaration
|
||||||
|
|| kind === SyntaxKind.BoltSourceFile;
|
||||||
|
}
|
||||||
|
|
||||||
function getFullName(node: Syntax) {
|
function getFullName(node: Syntax) {
|
||||||
let out = []
|
let out = []
|
||||||
let curr: Syntax | null = node;
|
let curr: Syntax | null = node;
|
||||||
|
@ -112,22 +153,19 @@ function getFullName(node: Syntax) {
|
||||||
|
|
||||||
export class TypeChecker {
|
export class TypeChecker {
|
||||||
|
|
||||||
protected symbols: FastStringMap<Type> = Object.create(null)
|
private symbols = new FastStringMap<string, Type>();
|
||||||
protected types = new Map<Syntax, Type>();
|
private types = new Map<Syntax, Type>();
|
||||||
protected scopes = new Map<Syntax, Scope>();
|
private scopes = new Map<Syntax, Scope>();
|
||||||
|
|
||||||
constructor() {
|
private inferTypeFromUsage(bindings: BoltPattern, body: BoltFunctionBodyElement[]) {
|
||||||
}
|
|
||||||
|
|
||||||
protected inferTypeFromUsage(bindings: BoltPattern, body: Body) {
|
|
||||||
return anyType;
|
return anyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTypeOfBody(body: Body) {
|
private getTypeOfBody(body: BoltFunctionBodyElement[]) {
|
||||||
return anyType;
|
return anyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected createType(node: Syntax): Type {
|
private createType(node: Syntax): Type {
|
||||||
|
|
||||||
console.error(`creating type for ${kindToString(node.kind)}`);
|
console.error(`creating type for ${kindToString(node.kind)}`);
|
||||||
|
|
||||||
|
@ -139,11 +177,6 @@ export class TypeChecker {
|
||||||
case SyntaxKind.BoltConstantExpression:
|
case SyntaxKind.BoltConstantExpression:
|
||||||
return node.value.type;
|
return node.value.type;
|
||||||
|
|
||||||
case SyntaxKind.BoltNewTypeDeclaration:
|
|
||||||
console.log(getFullName(node.name))
|
|
||||||
this.symbols[getFullName(node.name)] = new PrimType();
|
|
||||||
return noneType;
|
|
||||||
|
|
||||||
case SyntaxKind.BoltExpressionStatement:
|
case SyntaxKind.BoltExpressionStatement:
|
||||||
return voidType;
|
return voidType;
|
||||||
|
|
||||||
|
@ -171,21 +204,29 @@ export class TypeChecker {
|
||||||
})
|
})
|
||||||
return new FunctionType(paramTypes, returnType);
|
return new FunctionType(paramTypes, returnType);
|
||||||
|
|
||||||
case SyntaxKind.BoltReferenceTypeNode:
|
case SyntaxKind.BoltReferenceTypeExpression:
|
||||||
const name = getFullTextOfQualName(node.name);
|
const name = getFullTextOfQualName(node.name);
|
||||||
const reffed = this.getTypeNamed(name);
|
const scope = this.getScope(node);
|
||||||
|
let reffed = scope.getTypeNamed(name);
|
||||||
if (reffed === null) {
|
if (reffed === null) {
|
||||||
throw new Error(`Could not find a type named '${name}'`);
|
reffed = anyType;
|
||||||
}
|
}
|
||||||
return reffed;
|
return reffed;
|
||||||
|
|
||||||
case SyntaxKind.BoltRecordDeclaration:
|
case SyntaxKind.BoltRecordDeclaration:
|
||||||
|
|
||||||
const typ = new RecordType(map(node.fields, field => ([field.name.text, this.getTypeOfNode(field.type)])));
|
const fullName = getFullName(node);
|
||||||
|
let type;
|
||||||
|
|
||||||
this.symbols[getFullName(node)] = typ;
|
if (node.members === null) {
|
||||||
|
type = new PrimType();
|
||||||
|
this.symbols.set(fullName, type);
|
||||||
|
} else {
|
||||||
|
type = new RecordType(map(node.members, member => ([field.name.text, this.getTypeOfNode(field.type)])));
|
||||||
|
this.symbols.set(fullName, type);
|
||||||
|
}
|
||||||
|
|
||||||
return typ;
|
return type;
|
||||||
|
|
||||||
case SyntaxKind.BoltParameter:
|
case SyntaxKind.BoltParameter:
|
||||||
if (node.type !== null) {
|
if (node.type !== null) {
|
||||||
|
@ -200,13 +241,14 @@ export class TypeChecker {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getTypeNamed(name: string) {
|
public getSymbolNamed(name: string) {
|
||||||
return name in this.symbols
|
if (!this.symbols.has(name)) {
|
||||||
? this.symbols[name]
|
return null;
|
||||||
: null
|
}
|
||||||
|
return this.symbols.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTypeOfNode(node: Syntax): Type {
|
public getTypeOfNode(node: Syntax): Type {
|
||||||
if (this.types.has(node)) {
|
if (this.types.has(node)) {
|
||||||
return this.types.get(node)!
|
return this.types.get(node)!
|
||||||
}
|
}
|
||||||
|
@ -215,15 +257,13 @@ export class TypeChecker {
|
||||||
return newType;
|
return newType;
|
||||||
}
|
}
|
||||||
|
|
||||||
check(node: Syntax) {
|
public check(node: Syntax) {
|
||||||
|
|
||||||
this.getTypeOfNode(node);
|
this.getTypeOfNode(node);
|
||||||
|
|
||||||
switch (node.kind) {
|
switch (node.kind) {
|
||||||
|
|
||||||
case SyntaxKind.BoltSentence:
|
|
||||||
case SyntaxKind.BoltRecordDeclaration:
|
case SyntaxKind.BoltRecordDeclaration:
|
||||||
case SyntaxKind.BoltNewTypeDeclaration:
|
|
||||||
case SyntaxKind.BoltConstantExpression:
|
case SyntaxKind.BoltConstantExpression:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -267,12 +307,8 @@ export class TypeChecker {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getImportedSymbols(node: BoltImportDeclaration) {
|
public getScope(node: Syntax): Scope {
|
||||||
return [{ name: 'fac' }]
|
while (!introducesNewScope(node.kind)) {
|
||||||
}
|
|
||||||
|
|
||||||
getScope(node: Syntax): Scope {
|
|
||||||
while (node.kind !== SyntaxKind.BoltFunctionDeclaration && node.kind !== SyntaxKind.BoltSourceFile) {
|
|
||||||
node = node.parentNode!;
|
node = node.parentNode!;
|
||||||
}
|
}
|
||||||
if (this.scopes.has(node)) {
|
if (this.scopes.has(node)) {
|
||||||
|
@ -283,7 +319,7 @@ export class TypeChecker {
|
||||||
return scope
|
return scope
|
||||||
}
|
}
|
||||||
|
|
||||||
protected intersectTypes(a: Type, b: Type): Type {
|
private intersectTypes(a: Type, b: Type): Type {
|
||||||
if (a === noneType || b == noneType) {
|
if (a === noneType || b == noneType) {
|
||||||
return noneType;
|
return noneType;
|
||||||
}
|
}
|
||||||
|
@ -304,9 +340,5 @@ export class TypeChecker {
|
||||||
return noneType;
|
return noneType;
|
||||||
}
|
}
|
||||||
|
|
||||||
// getMapperForNode(target: string, node: Syntax): Mapper {
|
|
||||||
// return this.getScope(node).getMapper(target)
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
import { Syntax, SyntaxKind, Expr, isNode } from "./ast"
|
import { Syntax, SyntaxKind, Expr, isNode, BoltQualName } from "./ast"
|
||||||
import { TypeChecker, Type, RecordType, PrimType, boolType } from "./checker"
|
import { TypeChecker, Type, RecordType, PrimType, boolType } from "./checker"
|
||||||
import { FastStringMap } from "./util"
|
import { FastStringMap } from "./util"
|
||||||
|
|
||||||
|
@ -65,28 +65,32 @@ export class RecordWrapper extends RecordValue {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDeclarationPath(node: BoltQualName) {
|
||||||
|
return [...node.modulePath.map(id => id.text), node.name.text];
|
||||||
|
}
|
||||||
|
|
||||||
class Environment {
|
class Environment {
|
||||||
|
|
||||||
private symbols: FastStringMap<Value> = Object.create(null);
|
private symbols = FastStringMap<string, Value>();
|
||||||
|
|
||||||
constructor(public parentEnv: Environment | null = null) {
|
constructor(public parentEnv: Environment | null = null) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setValue(name: string, value: Value) {
|
public setValue(name: string, value: Value) {
|
||||||
if (name in this.symbols) {
|
if (name in this.symbols) {
|
||||||
throw new Error(`A variable with the name '${name}' already exists.`);
|
throw new Error(`A variable with the name '${name}' already exists.`);
|
||||||
}
|
}
|
||||||
this.symbols[name] = value;
|
this.symbols[name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateValue(name: string, newValue: Value) {
|
public updateValue(name: string, newValue: Value) {
|
||||||
if (!(name in this.symbols)) {
|
if (!(name in this.symbols)) {
|
||||||
throw new Error(`Trying to update a variable '${name}' that has not been declared.`);
|
throw new Error(`Trying to update a variable '${name}' that has not been declared.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lookup(name: string) {
|
public lookup(name: string) {
|
||||||
let curr = this as Environment;
|
let curr = this as Environment;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (name in curr.symbols) {
|
if (name in curr.symbols) {
|
||||||
|
@ -136,26 +140,26 @@ export class Evaluator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eval(node: Syntax, env: Environment = new Environment()): Value {
|
public eval(node: Syntax, env: Environment = new Environment()): Value {
|
||||||
|
|
||||||
switch (node.kind) {
|
switch (node.kind) {
|
||||||
|
|
||||||
case SyntaxKind.SourceFile:
|
case SyntaxKind.BoltSourceFile:
|
||||||
case SyntaxKind.Module:
|
case SyntaxKind.BoltModule:
|
||||||
for (const element of node.elements) {
|
for (const element of node.elements) {
|
||||||
this.eval(element, env);
|
this.eval(element, env);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SyntaxKind.RefExpr:
|
case SyntaxKind.BoltReferenceTypeExpression:
|
||||||
return env.lookup(node.name.fullText);
|
// FIXME
|
||||||
|
return env.lookup(node.name.name.text);
|
||||||
|
|
||||||
case SyntaxKind.NewTypeDecl:
|
case SyntaxKind.BoltRecordDeclaration:
|
||||||
case SyntaxKind.RecordDecl:
|
case SyntaxKind.BoltFunctionDeclaration:
|
||||||
case SyntaxKind.FuncDecl:
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SyntaxKind.MatchExpr:
|
case SyntaxKind.BoltMatchExpression:
|
||||||
const value = this.eval(node.value, env);
|
const value = this.eval(node.value, env);
|
||||||
for (const [pattern, result] of node.arms) {
|
for (const [pattern, result] of node.arms) {
|
||||||
if (this.match(value, pattern)) {
|
if (this.match(value, pattern)) {
|
||||||
|
@ -164,7 +168,7 @@ export class Evaluator {
|
||||||
}
|
}
|
||||||
return new PrimValue(this.checker.getTypeNamed('Void')!, null);
|
return new PrimValue(this.checker.getTypeNamed('Void')!, null);
|
||||||
|
|
||||||
case SyntaxKind.ConstExpr:
|
case SyntaxKind.BoltConstantExpression:
|
||||||
return new PrimValue(this.checker.getTypeOfNode(node), node.value)
|
return new PrimValue(this.checker.getTypeOfNode(node), node.value)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue