Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the CSET machine, along with macros #1728

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
126f216
add prelimiary framework for macro system
s-kybound Oct 3, 2024
2c0ed19
Allow Scheme data types as part of control
s-kybound Oct 7, 2024
334a87c
add functionality to scheme eval metaprocedure
s-kybound Oct 7, 2024
fbe3a1f
update macro skeleton
s-kybound Oct 24, 2024
19796ef
add pattern matching system prototype
s-kybound Oct 28, 2024
e0783fd
complete first iteration of pattern matching functions
s-kybound Oct 29, 2024
4798e07
finish first implementation of pattern matcher
s-kybound Oct 30, 2024
20c2b83
update tests for call/cc
s-kybound Oct 31, 2024
f31bf8b
complete CSEP machine behaviour for standard syntax forms
s-kybound Oct 31, 2024
eef4b12
add tags to modified estree nodes, and deparser
s-kybound Nov 2, 2024
4449d64
fix pattern matching logic
s-kybound Nov 2, 2024
255cd00
allow let, cond, etc... to be defined in the prelude
s-kybound Nov 2, 2024
8e97aad
allow runtime checks for basic forms
s-kybound Nov 2, 2024
8125486
remove hack of storing scheme lists in estree nodes
s-kybound Nov 2, 2024
db1c7b5
fix behaviour of ... in macros
s-kybound Nov 2, 2024
28c43f5
fix tests with scheme
s-kybound Nov 3, 2024
65ac67c
Merge branch 'source' into csep-machine
s-kybound Nov 3, 2024
1c80862
undo fix tests with scheme
s-kybound Nov 3, 2024
3cabbb8
reduce strictness of scm-slang parser for FULL_SCHEME
s-kybound Nov 3, 2024
0fc0c55
add more error-checking for CSEP machine
s-kybound Nov 3, 2024
10be628
add tests for CSEP machine and macros
s-kybound Nov 3, 2024
5c4cc35
rename csep machine to cset machine
s-kybound Nov 4, 2024
fa28000
implement the macro environment
s-kybound Nov 5, 2024
89dc10d
improve behaviour of CSET machine
s-kybound Nov 13, 2024
006ad1c
fix formatting issues
s-kybound Nov 13, 2024
a979a68
Clean up helper functions
s-kybound Nov 18, 2024
2d3247c
create apply metaprocedure
s-kybound Nov 18, 2024
fee864d
add tests for base cset machine and apply
s-kybound Nov 18, 2024
9b290ab
add named let to scheme prelude
s-kybound Nov 18, 2024
c3f0269
Merge branch 'master' into csep-machine
Nov 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/alt-langs/mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,11 @@ export function mapResult(context: Context): (x: Result) => Result {
// there is no need for a mapper in this case.
return x => x
}
}
}

export const isSchemeLanguage = (context: Context) =>
context.chapter === Chapter.SCHEME_1 ||
context.chapter === Chapter.SCHEME_2 ||
context.chapter === Chapter.SCHEME_3 ||
context.chapter === Chapter.SCHEME_4 ||
context.chapter === Chapter.FULL_SCHEME
26 changes: 14 additions & 12 deletions src/createContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import * as operators from './utils/operators'
import { stringify } from './utils/stringify'
import { schemeVisualise } from './alt-langs/scheme/scheme-mapper'
import { cset_apply, cset_eval } from './cse-machine/scheme-macros'
import { Transformers } from './cse-machine/interpreter'

export class LazyBuiltIn {
func: (...arg0: any) => any
Expand Down Expand Up @@ -117,6 +119,7 @@
nodes: [],
control: null,
stash: null,
transformers: new Transformers(),
objectCount: 0,
envSteps: -1,
envStepsTotal: 0,
Expand Down Expand Up @@ -422,7 +425,7 @@
'call_cc(f)',
context.variant === Variant.EXPLICIT_CONTROL
? call_with_current_continuation
: (f: any) => {

Check warning on line 428 in src/createContext.ts

View workflow job for this annotation

GitHub Actions / build

'f' is defined but never used. Allowed unused args must match /^_/u
throw new Error('call_cc is only available in Explicit-Control variant')
}
)
Expand Down Expand Up @@ -450,16 +453,14 @@
if (context.chapter <= +Chapter.SCHEME_1 && context.chapter >= +Chapter.FULL_SCHEME) {
switch (context.chapter) {
case Chapter.FULL_SCHEME:
// Introduction to eval
// eval metaprocedure
defineBuiltin(context, '$scheme_ZXZhbA$61$$61$(xs)', cset_eval)

case Chapter.SCHEME_4:
// Introduction to call/cc
defineBuiltin(context, 'call$47$cc(f)', call_with_current_continuation)

// Introduction to eval

// Scheme apply
// ^ is needed in Schemes 2 and 3 to apply to call functions with rest parameters,
// so we move it there.

case Chapter.SCHEME_3:
// Introduction to mutable values, streams

Expand Down Expand Up @@ -497,10 +498,6 @@
defineBuiltin(context, 'list$45$$62$vector(xs)', scheme_libs.list$45$$62$vector)

case Chapter.SCHEME_2:
// Splicing builtin resolvers
// defineBuiltin(context, '$36$make$45$splice(expr)', scheme_libs.make_splice)
// defineBuiltin(context, '$36$resolve$45$splice(xs)', scheme_libs.resolve_splice)

// Scheme pairs
defineBuiltin(context, 'cons(left, right)', scheme_libs.cons)
defineBuiltin(context, 'xcons(right, left)', scheme_libs.xcons)
Expand Down Expand Up @@ -622,11 +619,16 @@
defineBuiltin(context, 'list$45$$62$string(xs)', scheme_libs.list$45$$62$string)

// Scheme apply is needed here to help in the definition of the Scheme Prelude.
defineBuiltin(context, 'apply(f, ...args)', scheme_libs.apply, 2)
defineBuiltin(context, 'apply(f, ...args)', cset_apply, 2)

case Chapter.SCHEME_1:
// Display
defineBuiltin(context, 'display(val)', (val: any) => display(schemeVisualise(val)))
defineBuiltin(
context,
'display(val, prepend = undefined)',
(val: any, ...str: string[]) => display(schemeVisualise(val), ...str),
1
)
defineBuiltin(context, 'newline()', () => display(''))

// I/O
Expand Down
84 changes: 84 additions & 0 deletions src/cse-machine/__tests__/__snapshots__/cset-machine-apply.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`eval of strings: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(eval \\"hello\\")
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": "hello",
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`incorrect use of apply throws error (insufficient arguments): expectParsedError 1`] = `
Object {
"alertResult": Array [],
"code": "
(apply)
",
"displayResult": Array [],
"numErrors": 1,
"parsedErrors": "Expected 2 arguments, but got 0.",
"result": undefined,
"resultStatus": "error",
"visualiseListResult": Array [],
}
`;

exports[`incorrect use of apply throws error (last argument not a list): expectParsedError 1`] = `
Object {
"alertResult": Array [],
"code": "
(apply + 1 2 3)
",
"displayResult": Array [],
"numErrors": 1,
"parsedErrors": "Error: Last argument of apply must be a list",
"result": undefined,
"resultStatus": "error",
"visualiseListResult": Array [],
}
`;

exports[`multi-operand apply: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(define args '(1 2 3 4 5))
(apply + 6 7 8 9 10 args)
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": SchemeInteger {
"numberType": 1,
"value": 55n,
},
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`two-operand apply: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(define args '(1 2))
(apply + args)
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": SchemeInteger {
"numberType": 1,
"value": 3n,
},
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;
224 changes: 224 additions & 0 deletions src/cse-machine/__tests__/__snapshots__/cset-machine-eval.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`eval of application: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(eval '(+ 1 2))
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": SchemeInteger {
"numberType": 1,
"value": 3n,
},
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`eval of begin: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(eval '(begin 1 2 3))
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": SchemeInteger {
"numberType": 1,
"value": 3n,
},
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`eval of booleans: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(eval #t)
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": true,
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`eval of define: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(eval '(define x 1))
x
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": SchemeInteger {
"numberType": 1,
"value": 1n,
},
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`eval of empty list: expectParsedError 1`] = `
Object {
"alertResult": Array [],
"code": "
(eval '())
",
"displayResult": Array [],
"numErrors": 1,
"parsedErrors": "Error: Cannot evaluate null",
"result": undefined,
"resultStatus": "error",
"visualiseListResult": Array [],
}
`;

exports[`eval of if: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(eval '(if #t 1 2))
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": SchemeInteger {
"numberType": 1,
"value": 1n,
},
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`eval of lambda: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(eval '(lambda (x) x))
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": [Function],
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`eval of numbers: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(eval 1)
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": SchemeInteger {
"numberType": 1,
"value": 1n,
},
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`eval of quote: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(eval '(quote (1 2 3)))
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": Array [
SchemeInteger {
"numberType": 1,
"value": 1n,
},
Array [
SchemeInteger {
"numberType": 1,
"value": 2n,
},
Array [
SchemeInteger {
"numberType": 1,
"value": 3n,
},
null,
],
],
],
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`eval of set!: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(define x 2)
(eval '(set! x 1))
x
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": SchemeInteger {
"numberType": 1,
"value": 1n,
},
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`eval of strings: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(eval \\"hello\\")
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": "hello",
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;

exports[`eval of symbols: expectResult 1`] = `
Object {
"alertResult": Array [],
"code": "
(define hello 1)
(eval 'hello)
",
"displayResult": Array [],
"numErrors": 0,
"parsedErrors": "",
"result": SchemeInteger {
"numberType": 1,
"value": 1n,
},
"resultStatus": "finished",
"visualiseListResult": Array [],
}
`;
Loading
Loading