initial ideas

This commit is contained in:
dylan
2023-04-28 17:57:35 -07:00
parent 3e7bf2dd80
commit 3390e9d50a
11 changed files with 1362 additions and 0 deletions

133
femto-lang/faux/faux.ts Normal file
View File

@ -0,0 +1,133 @@
// const STR = (s: string): StringValue => ({type: "string", value: s});
// const FN = (f: FunctionValue["value"]): FunctionValue => ({type: "function", value: f});
// const SYM = (s: string): SymbolValue => ({type: "symbol", value: s});
// const UNDEF = (): UndefinedValue => ({type: "undefined", value: null});
// const CODE = (p: CodeBlockValue["value"]): CodeBlockValue => ({type: "code", value: p});
// const THUNK = (t: ThunkValue["value"]): ThunkValue => ({type: "thunk", value: t});
// const BOOL = (b: boolean): BooleanValue => ({type: "boolean", value: b});
// console.log("HELLO");
// type SymbolValue = {
// type: "symbol",
// value: string,
// }
// type FunctionValue = {
// type: "function",
// value: (arg: Value, env: Environment, passalong: Passalong) => Result,
// }
// type StringValue = {
// type: "string",
// value: string,
// }
// type BooleanValue = {
// type: "boolean",
// value: boolean,
// }
// type UndefinedValue = {
// type: "undefined",
// value: null,
// }
// type CodeBlockValue = {
// type: "code",
// value: Array<Value>,
// }
// type ThunkValue = {
// type: "thunk",
// value: Array<Value>,
// }
// type Value =
// | SymbolValue
// | FunctionValue
// | StringValue
// | UndefinedValue
// | CodeBlockValue
// | ThunkValue
// | BooleanValue
// type Passalong = Value;
// type Result<V extends Value = Value> = {
// result: V,
// passalong: any,
// }
// type Environment = {[key: string]: Value}
// const evaluate_codeblock = (codeBlock: CodeBlockValue, env: Environment): Result => {
// let result: Result = {
// result: UNDEF(),
// passalong: UNDEF(),
// };
// const terms = [...codeBlock.value];
// while (terms.length) {
// console.log('evaluating phrase', terms);
// result = evaluate_phrase(terms, env, result.passalong);
// }
// return result;
// }
// const evaluate_phrase = (terms: Array<Value>, env: Environment, passalong: Passalong): Result => {
// let head: Result = evaluate_term(terms.shift() as Value, env, passalong);
// let pa = passalong;
// while (head.result.type === "function") {
// if (!terms.length) {
// throw 'Runtime Error: head function has no argument to be called with';
// }
// const tail: Result = evaluate_term(terms.shift() as Value, env, UNDEF());
// head = head.result.value(tail.result, env, pa);
// pa = head.passalong;
// }
// return head;
// }
// const evaluate_term = (term: Value, env: Environment, passalong: Passalong): Result => {
// if (term.type === "symbol") {
// return {
// result: env[term.value],
// passalong: UNDEF(), // TODO: this should include term.value as a "name"
// }
// } else if (term.type === "string") {
// return {
// result: term,
// passalong: UNDEF(),
// }
// } else if (term.type === "function") {
// return {
// result: term,
// passalong: UNDEF(),
// }
// } else if (term.type === "boolean") {
// return {
// result: term,
// passalong: UNDEF(),
// }
// }
// return {
// result: UNDEF(),
// passalong: UNDEF(),
// }
// }
// const my_env: Environment = {
// print: FN((arg, env, passalong) => {
// console.log(arg);
// return {
// result: UNDEF(),
// passalong: UNDEF(),
// }
// })
// }
// const my_prog: CodeBlockValue = CODE([
// SYM("print"), STR("hi"),
// ]);
// console.log(evaluate_codeblock(my_prog, my_env));

141
femto-lang/faux/trying.js Normal file
View File

@ -0,0 +1,141 @@
const STR = (s) => ({type: "string", value: s});
const FN = (f) => ({type: "function", value: f});
const SYM = (s) => ({type: "symbol", value: s});
const UNDEF = () => ({type: "undefined", value: null});
const CODE = (p) => ({type: "code", value: p});
const THUNK = (t) => ({type: "thunk", value: t});
const BOOL = (b) => ({type: "boolean", value: b});
const evaluate_codeblock = (codeBlock, env) => {
let result = {
result: UNDEF(),
passalong: {},
};
const terms = [...codeBlock.value];
while (terms.length) {
// console.log('evaluating phrase', terms);
result = evaluate_phrase(terms, env, result.passalong);
}
return result;
}
const evaluate_phrase = (terms, env, passalong) => {
let head = evaluate_term(terms.shift(), env, passalong);
let pa = passalong;
while (head.result.type === "function") {
if (!terms.length) {
throw 'Runtime Error: head function has no argument to be called with';
}
const tail = evaluate_term(terms.shift(), env, {});
head = head.result.value(tail.result, env, pa);
pa = head.passalong;
}
return head;
}
const evaluate_term = (term, env, passalong) => {
if (term.type === "symbol") {
return {
result: env[term.value],
passalong: {name: STR(term.value)}, // TODO: this should include term.value as a "name"
}
} else if (term.type === "string") {
return {
result: term,
passalong: {},
}
} else if (term.type === "function") {
return {
result: term,
passalong: {},
}
} else if (term.type === "boolean") {
return {
result: term,
passalong: {},
}
} else if (term.type === "thunk") {
return {
result: term,
passalong: {},
}
}
return {
result: UNDEF(),
passalong: {},
}
}
const my_env = {
print: FN((arg, env, passalong) => {
console.log('PRINT', arg);
return {
result: UNDEF(),
passalong: {},
}
}),
if: FN((arg, env, passalong) => {
return {
result: FN((thunk, e2, pa) => {
if (arg.type === "boolean" && arg.value) {
return {
result: evaluate_codeblock(thunk, e2),
passalong: {handled: true},
}
} else {
return {
result: UNDEF(),
passalong: {handled: false},
}
}
}),
passalong: {},
}
}),
else: FN((thunk, env, passalong) => {
if (!passalong.handled) {
return {
result: evaluate_codeblock(thunk, env),
passalong: {handled: true},
}
} else {
return {
result: UNDEF(),
passalong: {handled: true},
}
}
}),
}
`
print "hi"
if false {
print "hi2"
} else {
print "hi3"
}
set x = 10
set y = 20
set f = fn h => {
print h
print h
}
f x
for value in obj {
}
`
const my_prog = CODE([
SYM("print"), STR("hi"),
SYM("if"), BOOL(false), THUNK([
SYM("print"), STR("hi2"),
]),
SYM("else"), THUNK([
SYM("print"), STR("hi3"),
]),
]);
console.log(evaluate_codeblock(my_prog, my_env));