getting there bro
This commit is contained in:
parent
3a12d7baff
commit
023bfb2caa
|
|
@ -25,6 +25,7 @@ export class Compiler {
|
||||||
fnLabels = new Map<Label, ProgramItem[]>()
|
fnLabels = new Map<Label, ProgramItem[]>()
|
||||||
ifLabelCount = 0
|
ifLabelCount = 0
|
||||||
bytecode: Bytecode
|
bytecode: Bytecode
|
||||||
|
pipeCounter = 0
|
||||||
|
|
||||||
constructor(public input: string) {
|
constructor(public input: string) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -38,12 +39,6 @@ export class Compiler {
|
||||||
|
|
||||||
this.#compileCst(cst, input)
|
this.#compileCst(cst, input)
|
||||||
|
|
||||||
throw new CompilerError(
|
|
||||||
'I am a very long fake error to test scrolling and other things this is super long\nand has multiple lines\nand just keeps going and going and going',
|
|
||||||
20,
|
|
||||||
25
|
|
||||||
)
|
|
||||||
|
|
||||||
// Add the labels
|
// Add the labels
|
||||||
for (const [label, labelInstructions] of this.fnLabels) {
|
for (const [label, labelInstructions] of this.fnLabels) {
|
||||||
this.instructions.push([`${label}:`])
|
this.instructions.push([`${label}:`])
|
||||||
|
|
@ -146,7 +141,7 @@ export class Compiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
case terms.FunctionDef: {
|
case terms.FunctionDef: {
|
||||||
const { paramNames, bodyNode } = getFunctionDefParts(node, input)
|
const { paramNames, bodyNodes } = getFunctionDefParts(node, input)
|
||||||
const instructions: ProgramItem[] = []
|
const instructions: ProgramItem[] = []
|
||||||
const functionLabel: Label = `.func_${this.fnLabels.size}`
|
const functionLabel: Label = `.func_${this.fnLabels.size}`
|
||||||
const bodyInstructions: ProgramItem[] = []
|
const bodyInstructions: ProgramItem[] = []
|
||||||
|
|
@ -157,7 +152,9 @@ export class Compiler {
|
||||||
this.fnLabels.set(functionLabel, bodyInstructions)
|
this.fnLabels.set(functionLabel, bodyInstructions)
|
||||||
|
|
||||||
instructions.push(['MAKE_FUNCTION', paramNames, functionLabel])
|
instructions.push(['MAKE_FUNCTION', paramNames, functionLabel])
|
||||||
|
bodyNodes.forEach((bodyNode) => {
|
||||||
bodyInstructions.push(...this.#compileNode(bodyNode, input))
|
bodyInstructions.push(...this.#compileNode(bodyNode, input))
|
||||||
|
})
|
||||||
|
|
||||||
return instructions
|
return instructions
|
||||||
}
|
}
|
||||||
|
|
@ -311,8 +308,10 @@ export class Compiler {
|
||||||
const instructions: ProgramItem[] = []
|
const instructions: ProgramItem[] = []
|
||||||
instructions.push(...this.#compileNode(pipedFunctionCall, input))
|
instructions.push(...this.#compileNode(pipedFunctionCall, input))
|
||||||
|
|
||||||
|
this.pipeCounter++
|
||||||
|
const pipeValName = `_pipe_value_${this.pipeCounter}`
|
||||||
pipeReceivers.forEach((pipeReceiver) => {
|
pipeReceivers.forEach((pipeReceiver) => {
|
||||||
instructions.push(['STORE', '_pipe_value'])
|
instructions.push(['STORE', pipeValName])
|
||||||
|
|
||||||
const { identifierNode, namedArgs, positionalArgs } = getFunctionCallParts(
|
const { identifierNode, namedArgs, positionalArgs } = getFunctionCallParts(
|
||||||
pipeReceiver,
|
pipeReceiver,
|
||||||
|
|
@ -333,12 +332,12 @@ export class Compiler {
|
||||||
|
|
||||||
// If no underscore is explicitly used, add the piped value as the first positional arg
|
// If no underscore is explicitly used, add the piped value as the first positional arg
|
||||||
if (shouldPushPositionalArg) {
|
if (shouldPushPositionalArg) {
|
||||||
instructions.push(['LOAD', '_pipe_value'])
|
instructions.push(['LOAD', pipeValName])
|
||||||
}
|
}
|
||||||
|
|
||||||
positionalArgs.forEach((arg) => {
|
positionalArgs.forEach((arg) => {
|
||||||
if (arg.type.id === terms.Underscore) {
|
if (arg.type.id === terms.Underscore) {
|
||||||
instructions.push(['LOAD', '_pipe_value'])
|
instructions.push(['LOAD', pipeValName])
|
||||||
} else {
|
} else {
|
||||||
instructions.push(...this.#compileNode(arg, input))
|
instructions.push(...this.#compileNode(arg, input))
|
||||||
}
|
}
|
||||||
|
|
@ -348,7 +347,7 @@ export class Compiler {
|
||||||
const { name, valueNode } = getNamedArgParts(arg, input)
|
const { name, valueNode } = getNamedArgParts(arg, input)
|
||||||
instructions.push(['PUSH', name])
|
instructions.push(['PUSH', name])
|
||||||
if (valueNode.type.id === terms.Underscore) {
|
if (valueNode.type.id === terms.Underscore) {
|
||||||
instructions.push(['LOAD', '_pipe_value'])
|
instructions.push(['LOAD', pipeValName])
|
||||||
} else {
|
} else {
|
||||||
instructions.push(...this.#compileNode(valueNode, input))
|
instructions.push(...this.#compileNode(valueNode, input))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,9 +59,9 @@ export const getAssignmentParts = (node: SyntaxNode) => {
|
||||||
|
|
||||||
export const getFunctionDefParts = (node: SyntaxNode, input: string) => {
|
export const getFunctionDefParts = (node: SyntaxNode, input: string) => {
|
||||||
const children = getAllChildren(node)
|
const children = getAllChildren(node)
|
||||||
const [fnKeyword, paramsNode, colon, bodyNode] = children
|
const [fnKeyword, paramsNode, colon, ...bodyNodes] = children
|
||||||
|
|
||||||
if (!fnKeyword || !paramsNode || !colon || !bodyNode) {
|
if (!fnKeyword || !paramsNode || !colon || !bodyNodes) {
|
||||||
throw new CompilerError(
|
throw new CompilerError(
|
||||||
`FunctionDef expected 5 children, got ${children.length}`,
|
`FunctionDef expected 5 children, got ${children.length}`,
|
||||||
node.from,
|
node.from,
|
||||||
|
|
@ -80,7 +80,8 @@ export const getFunctionDefParts = (node: SyntaxNode, input: string) => {
|
||||||
return input.slice(param.from, param.to)
|
return input.slice(param.from, param.to)
|
||||||
})
|
})
|
||||||
|
|
||||||
return { paramNames, bodyNode }
|
const bodyWithoutEnd = bodyNodes.slice(0, -1)
|
||||||
|
return { paramNames, bodyNodes: bodyWithoutEnd }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getFunctionCallParts = (node: SyntaxNode, input: string) => {
|
export const getFunctionCallParts = (node: SyntaxNode, input: string) => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user