mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-09 04:59:31 -06:00
Add tests for reading & equality of various expressions
This commit is contained in:
@@ -71,9 +71,10 @@ export class ExprLit extends Expr {
|
||||
export class ExprMeta extends Expr {
|
||||
id: number
|
||||
|
||||
constructor (i: number) {
|
||||
constructor (i?: number) {
|
||||
super()
|
||||
this.id = i
|
||||
if (i != null) this.id = i
|
||||
else this.id = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -159,9 +159,9 @@ export function PgfText_FromString (str: string): Pointer<any> {
|
||||
// Un/marshalling
|
||||
|
||||
const eabs = ffi.Callback(PgfExpr, [PgfUnmarshaller, ref.types.bool, PgfTextPtr, PgfExpr],
|
||||
function (self, btype: boolean, name: Pointer<any>, body: Pointer<any>): Pointer<ExprAbs> {
|
||||
function (self, btype: boolean, name: Pointer<any>, body: Pointer<Expr>): Pointer<ExprAbs> {
|
||||
const jsname = PgfText_AsString(name)
|
||||
const obj = new ExprAbs(btype, jsname, body) // TODO check body
|
||||
const obj = new ExprAbs(btype, jsname, body.deref())
|
||||
const buf = ref.alloc(ref.types.Object) as Pointer<ExprAbs>
|
||||
ref.writeObject(buf, 0, obj)
|
||||
return buf
|
||||
@@ -169,7 +169,7 @@ const eabs = ffi.Callback(PgfExpr, [PgfUnmarshaller, ref.types.bool, PgfTextPtr,
|
||||
|
||||
const eapp = ffi.Callback(PgfExpr, [PgfUnmarshaller, PgfExpr, PgfExpr],
|
||||
function (self, fun: Pointer<Expr>, arg: Pointer<Type>): Pointer<ExprApp> {
|
||||
const obj = new ExprApp(fun, arg) // TODO check
|
||||
const obj = new ExprApp(fun.deref(), arg.deref())
|
||||
const buf = ref.alloc(ref.types.Object) as Pointer<ExprApp>
|
||||
ref.writeObject(buf, 0, obj)
|
||||
return buf
|
||||
@@ -211,7 +211,7 @@ const evar = ffi.Callback(PgfExpr, [PgfUnmarshaller, ref.types.int],
|
||||
|
||||
const etyped = ffi.Callback(PgfExpr, [PgfUnmarshaller, PgfExpr, PgfType],
|
||||
function (self, expr: Pointer<Expr>, type: Pointer<Type>): Pointer<ExprTyped> {
|
||||
const obj = new ExprTyped(expr, type.deref()) // TODO check
|
||||
const obj = new ExprTyped(expr.deref(), type.deref())
|
||||
const buf = ref.alloc(ref.types.Object) as Pointer<ExprTyped>
|
||||
ref.writeObject(buf, 0, obj)
|
||||
return buf
|
||||
@@ -219,7 +219,7 @@ const etyped = ffi.Callback(PgfExpr, [PgfUnmarshaller, PgfExpr, PgfType],
|
||||
|
||||
const eimplarg = ffi.Callback(PgfExpr, [PgfUnmarshaller, PgfExpr],
|
||||
function (self, expr: Pointer<Expr>): Pointer<ExprImplArg> {
|
||||
const obj = new ExprImplArg(expr) // TODO check
|
||||
const obj = new ExprImplArg(expr.deref())
|
||||
const buf = ref.alloc(ref.types.Object) as Pointer<ExprImplArg>
|
||||
ref.writeObject(buf, 0, obj)
|
||||
return buf
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
|
||||
import errno from './errno'
|
||||
import { Expr, ExprLit } from './expr'
|
||||
import {
|
||||
Type,
|
||||
Hypo,
|
||||
Expr,
|
||||
ExprAbs,
|
||||
ExprApp,
|
||||
ExprLit,
|
||||
ExprMeta,
|
||||
ExprFun,
|
||||
ExprVar,
|
||||
ExprTyped,
|
||||
ExprImplArg,
|
||||
Literal
|
||||
} from './expr'
|
||||
import {
|
||||
voidPtr,
|
||||
PgfRevisionPtr,
|
||||
@@ -67,7 +80,7 @@ function handleError (err: StructObject<PgfExnType>): void {
|
||||
// ----------------------------------------------------------------------------
|
||||
// PGF grammar object
|
||||
|
||||
export class PGFGrammar {
|
||||
class PGFGrammar {
|
||||
readonly db: Pointer<any>
|
||||
readonly revision: Pointer<any>
|
||||
|
||||
@@ -198,6 +211,15 @@ function newNGF (abstract_name: string, path?: string): PGFGrammar {
|
||||
return new PGFGrammar(db, rev)
|
||||
}
|
||||
|
||||
function readType (str: string): Type {
|
||||
const txt = PgfText_FromString(str)
|
||||
const type = runtime.pgf_read_type(txt, unmarshaller.ref())
|
||||
if (ref.isNull(type)) {
|
||||
throw new PGFError('unable to parse type')
|
||||
}
|
||||
return ref.readObject(type) as Type
|
||||
}
|
||||
|
||||
function readExpr (str: string): Expr {
|
||||
const txt = PgfText_FromString(str)
|
||||
const expr = runtime.pgf_read_expr(txt, unmarshaller.ref())
|
||||
@@ -210,15 +232,51 @@ function readExpr (str: string): Expr {
|
||||
// ----------------------------------------------------------------------------
|
||||
// Exposed library API
|
||||
|
||||
export default {
|
||||
export {
|
||||
PGFGrammar,
|
||||
PGFError,
|
||||
readPGF,
|
||||
bootNGF,
|
||||
readNGF,
|
||||
newNGF,
|
||||
|
||||
readType,
|
||||
readExpr,
|
||||
|
||||
Type,
|
||||
Hypo,
|
||||
Expr,
|
||||
ExprLit
|
||||
ExprAbs,
|
||||
ExprApp,
|
||||
ExprLit,
|
||||
ExprMeta,
|
||||
ExprFun,
|
||||
ExprVar,
|
||||
ExprTyped,
|
||||
ExprImplArg,
|
||||
Literal
|
||||
}
|
||||
export default {
|
||||
PGFGrammar,
|
||||
PGFError,
|
||||
readPGF,
|
||||
bootNGF,
|
||||
readNGF,
|
||||
newNGF,
|
||||
|
||||
readType,
|
||||
readExpr,
|
||||
|
||||
Type,
|
||||
Hypo,
|
||||
Expr,
|
||||
ExprAbs,
|
||||
ExprApp,
|
||||
ExprLit,
|
||||
ExprMeta,
|
||||
ExprFun,
|
||||
ExprVar,
|
||||
ExprTyped,
|
||||
ExprImplArg,
|
||||
Literal
|
||||
}
|
||||
|
||||
@@ -1,4 +1,19 @@
|
||||
import PGF, { PGFGrammar } from '../index'
|
||||
import PGF, {
|
||||
PGFError,
|
||||
PGFGrammar,
|
||||
// Type,
|
||||
// Hypo,
|
||||
// Expr,
|
||||
// ExprAbs,
|
||||
ExprApp,
|
||||
ExprLit,
|
||||
ExprMeta,
|
||||
ExprFun,
|
||||
// ExprVar,
|
||||
// ExprTyped,
|
||||
ExprImplArg
|
||||
// Literal
|
||||
} from '../index'
|
||||
import fs from 'fs'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -17,7 +32,7 @@ describe('readPGF', () => {
|
||||
test('GF', () => {
|
||||
expect(() => {
|
||||
PGF.readPGF('../haskell/tests/basic.gf')
|
||||
}).toThrow(PGF.PGFError)
|
||||
}).toThrow(PGFError)
|
||||
})
|
||||
|
||||
test('NGF', () => {
|
||||
@@ -29,7 +44,7 @@ describe('readPGF', () => {
|
||||
PGF.bootNGF('../haskell/tests/basic.pgf', './basic.ngf')
|
||||
expect(() => {
|
||||
PGF.readPGF('./basic.ngf')
|
||||
}).toThrow(PGF.PGFError)
|
||||
}).toThrow(PGFError)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -57,13 +72,13 @@ describe('bootNGF', () => {
|
||||
test('GF', () => {
|
||||
expect(() => {
|
||||
PGF.bootNGF('../haskell/tests/basic.gf', './abc.ngf')
|
||||
}).toThrow(PGF.PGFError)
|
||||
}).toThrow(PGFError)
|
||||
})
|
||||
|
||||
test('NGF', () => {
|
||||
expect(() => {
|
||||
PGF.bootNGF('./basic.ngf', './abc.ngf')
|
||||
}).toThrow(PGF.PGFError)
|
||||
}).toThrow(PGFError)
|
||||
})
|
||||
|
||||
test('existing', () => {
|
||||
@@ -98,13 +113,13 @@ describe('readNGF', () => {
|
||||
test('GF', () => {
|
||||
expect(() => {
|
||||
PGF.readNGF('../haskell/tests/basic.gf')
|
||||
}).toThrow(PGF.PGFError)
|
||||
}).toThrow(PGFError)
|
||||
})
|
||||
|
||||
test('PGF', () => {
|
||||
expect(() => {
|
||||
PGF.readNGF('../haskell/tests/basic.pgf')
|
||||
}).toThrow(PGF.PGFError)
|
||||
}).toThrow(PGFError)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -209,88 +224,170 @@ describe('abstract syntax', () => {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
describe('types', () => {
|
||||
test('invalid', () => {
|
||||
expect(() => {
|
||||
PGF.readType('->')
|
||||
}).toThrow(PGFError)
|
||||
})
|
||||
})
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
describe('expressions', () => {
|
||||
test('invalid', () => {
|
||||
expect(() => {
|
||||
PGF.readExpr('->')
|
||||
}).toThrow(PGF.PGFError)
|
||||
}).toThrow(PGFError)
|
||||
})
|
||||
|
||||
describe('literals', () => {
|
||||
test('small integer', () => {
|
||||
const e1 = PGF.readExpr('123')
|
||||
const e2 = new PGF.ExprLit(123)
|
||||
const e3 = new PGF.ExprLit(456)
|
||||
const e2 = new ExprLit(123)
|
||||
const e3 = new ExprLit(456)
|
||||
expect(e1).toEqual(e2)
|
||||
expect(e1).not.toEqual(e3)
|
||||
})
|
||||
|
||||
test('negative integer', () => {
|
||||
const e1 = PGF.readExpr('-123')
|
||||
const e2 = new PGF.ExprLit(-123)
|
||||
const e3 = new PGF.ExprLit(-456)
|
||||
const e2 = new ExprLit(-123)
|
||||
const e3 = new ExprLit(-456)
|
||||
expect(e1).toEqual(e2)
|
||||
expect(e1).not.toEqual(e3)
|
||||
})
|
||||
|
||||
test('big integer', () => {
|
||||
const e1 = PGF.readExpr('774763251095801167872')
|
||||
const e2 = new PGF.ExprLit(BigInt('774763251095801167872'))
|
||||
const e2 = new ExprLit(BigInt('774763251095801167872'))
|
||||
expect(e1).toEqual(e2)
|
||||
})
|
||||
|
||||
test('negative big integer', () => {
|
||||
const e1 = PGF.readExpr('-774763251095801167872')
|
||||
const e2 = new PGF.ExprLit(BigInt('-774763251095801167872'))
|
||||
const e2 = new ExprLit(BigInt('-774763251095801167872'))
|
||||
expect(e1).toEqual(e2)
|
||||
})
|
||||
|
||||
test('really big integer', () => {
|
||||
const e1 = PGF.readExpr('7747632510958011678729003251095801167999')
|
||||
const e2 = new PGF.ExprLit(BigInt('7747632510958011678729003251095801167999'))
|
||||
const e3 = new PGF.ExprLit(BigInt('7747632510958011678729003251095801167990'))
|
||||
const e2 = new ExprLit(BigInt('7747632510958011678729003251095801167999'))
|
||||
const e3 = new ExprLit(BigInt('7747632510958011678729003251095801167990'))
|
||||
expect(e1).toEqual(e2)
|
||||
expect(e1).not.toEqual(e3)
|
||||
})
|
||||
|
||||
test('negative really big integer', () => {
|
||||
const e1 = PGF.readExpr('-7747632510958011678729003251095801167999')
|
||||
const e2 = new PGF.ExprLit(BigInt('-7747632510958011678729003251095801167999'))
|
||||
const e3 = new PGF.ExprLit(BigInt('-7747632510958011678729003251095801167990'))
|
||||
const e2 = new ExprLit(BigInt('-7747632510958011678729003251095801167999'))
|
||||
const e3 = new ExprLit(BigInt('-7747632510958011678729003251095801167990'))
|
||||
expect(e1).toEqual(e2)
|
||||
expect(e1).not.toEqual(e3)
|
||||
})
|
||||
|
||||
test('float', () => {
|
||||
const e1 = PGF.readExpr('3.142')
|
||||
const e2 = new PGF.ExprLit(3.142)
|
||||
const e3 = new PGF.ExprLit(2.014)
|
||||
const e2 = new ExprLit(3.142)
|
||||
const e3 = new ExprLit(2.014)
|
||||
expect(e1).toEqual(e2)
|
||||
expect(e1).not.toEqual(e3)
|
||||
})
|
||||
|
||||
test('negative float', () => {
|
||||
const e1 = PGF.readExpr('-3.142')
|
||||
const e2 = new PGF.ExprLit(-3.142)
|
||||
const e3 = new PGF.ExprLit(-2.014)
|
||||
const e2 = new ExprLit(-3.142)
|
||||
const e3 = new ExprLit(-2.014)
|
||||
expect(e1).toEqual(e2)
|
||||
expect(e1).not.toEqual(e3)
|
||||
})
|
||||
|
||||
test('string', () => {
|
||||
const e1 = PGF.readExpr('"abc"')
|
||||
const e2 = new PGF.ExprLit('abc')
|
||||
const e3 = new PGF.ExprLit('def')
|
||||
const e2 = new ExprLit('abc')
|
||||
const e3 = new ExprLit('def')
|
||||
expect(e1).toEqual(e2)
|
||||
expect(e1).not.toEqual(e3)
|
||||
})
|
||||
|
||||
test('string unicode', () => {
|
||||
const e1 = PGF.readExpr('"açġħ"')
|
||||
const e2 = new PGF.ExprLit('açġħ')
|
||||
const e3 = new PGF.ExprLit('acgh')
|
||||
const e2 = new ExprLit('açġħ')
|
||||
const e3 = new ExprLit('acgh')
|
||||
expect(e1).toEqual(e2)
|
||||
expect(e1).not.toEqual(e3)
|
||||
})
|
||||
})
|
||||
|
||||
describe('functions', () => {
|
||||
test('simple', () => {
|
||||
const e1 = PGF.readExpr('f')
|
||||
expect(e1).toBeInstanceOf(ExprFun)
|
||||
expect((e1 as ExprFun).name).toEqual('f')
|
||||
|
||||
const e2 = new ExprFun('f')
|
||||
const e3 = new ExprFun('g')
|
||||
expect(e1).toEqual(e2)
|
||||
expect(e1).not.toEqual(e3)
|
||||
})
|
||||
|
||||
test('application 1', () => {
|
||||
const e1 = PGF.readExpr('f x y')
|
||||
expect(e1).toBeInstanceOf(ExprApp)
|
||||
expect((e1 as ExprApp).arg).toEqual(new ExprFun('y'))
|
||||
|
||||
const e2 = new ExprApp(
|
||||
new ExprApp(
|
||||
new ExprFun('f'),
|
||||
new ExprFun('x')
|
||||
), new ExprFun('y')
|
||||
)
|
||||
expect(e1).toEqual(e2)
|
||||
})
|
||||
|
||||
test('application 2', () => {
|
||||
const e1 = PGF.readExpr('f (g x)')
|
||||
const e2 = new ExprApp(
|
||||
new ExprFun('f'),
|
||||
new ExprApp(
|
||||
new ExprFun('g'),
|
||||
new ExprFun('x')
|
||||
)
|
||||
)
|
||||
expect(e1).toEqual(e2)
|
||||
})
|
||||
|
||||
test('application 3', () => {
|
||||
const e1 = PGF.readExpr('f {g x}')
|
||||
const e2 = new ExprApp(
|
||||
new ExprFun('f'),
|
||||
new ExprImplArg(
|
||||
new ExprApp(
|
||||
new ExprFun('g'),
|
||||
new ExprFun('x')
|
||||
)
|
||||
)
|
||||
)
|
||||
expect(e1).toEqual(e2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('variables', () => {
|
||||
test('meta 1', () => {
|
||||
const e1 = PGF.readExpr('?')
|
||||
expect(e1).toBeInstanceOf(ExprMeta)
|
||||
const e2 = new ExprMeta()
|
||||
const e3 = new ExprMeta(0)
|
||||
const e4 = new ExprMeta(1)
|
||||
expect(e1).toEqual(e2)
|
||||
expect(e1).toEqual(e3)
|
||||
expect(e1).not.toEqual(e4)
|
||||
})
|
||||
|
||||
test('meta 2', () => {
|
||||
const e1 = PGF.readExpr('?42')
|
||||
const e2 = new ExprMeta(42)
|
||||
expect(e1).toEqual(e2)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user