diff --git a/src/main.md b/src/main.md index ddab881..bc40d72 100644 --- a/src/main.md +++ b/src/main.md @@ -1,3 +1,7 @@ +# Lambda-mmm: the Intermediate Representation for Synchronous Signal Processing Language Based on Lambda Calculus + +Tomoya Matsuura(Tokyo Unviersity of the Arts) me@matsuuratomoya.com + ## Abstract This paper proposes $\lambda_{mmm}$, a call-by-value, simply typed lambda calculus-based intermediate representation for a music programming language that handles synchronous signal processing and introduces a virtual machine and instruction set to execute $\lambda_{mmm}$. Digital signal processing is represented by a syntax that incorporates the internal states of delay and feedback into the lambda calculus. $\lambda_{mmm}$ extends the lambda calculus, allowing users to construct generative signal processing graphs and execute them with consistent semantics. However, a challenge arises when handling higher-order functions because users must determine whether execution occurs within the global environment or during DSP execution. This issue can potentially be resolved through multi-stage computation. @@ -188,17 +192,20 @@ In addition to Lua's upvalue operations, four new operations--- `GETSTATE`, `SET MOVECONST A B R(A) := K(B) GETUPVALUE A B R(A) := U(B) SETUPVALUE A B U(B) := R(A) - GETSTATE A R(A) := SPtr[SPos] - SETSTATE A Sptr[SPos] := R(A) - SHIFTSTATE sAx SPos += sAx - DELAY A B R(A) := update_ringbuffer(SPtr[SPos],R(B)) + GETSTATE A R(A) := SPtr[SPos] * + SETSTATE A Sptr[SPos] := R(A) * + SHIFTSTATE sAx SPos += sAx * + DELAY A B C R(A) := update_ringbuffer(SPtr[SPos],R(B),R(C)) * +//*(SPos,SPtr)= vm.closures[vm.statepos_stack.top()].state +//(if vm.statepos_stack is empty, use global state storage.) JMP sAx PC +=sAx JMPIFNEG A sBx if (R(A)\<0) then PC += sBx - CALL A B C R(A),\...,R(A+C-2) := program.functions\[R(A)\](R(A+1),\...,R(A+B-1)) - CALLCLS A B C Sptr := vm.closures\[R(A)\].Sptr -     R(A),\...,R(A+C-2) := vm.closures\[R(A)\].fnproto(R(A+1),\...,R(A+B-1)) - Sptr := vm.global_sptr - CLOSURE A Bx vm.closures.push(closure(program.functions\[R(Bx)\])) R(A) := vm.closures.length - 1 + CALL A B C R(A),...,R(A+C-2) := program.functions[R(A)](R(A+1),...,R(A+B-1)) + CALLCLS A B C vm.statepos_stack.push(R(A)) +     R(A),...,R(A+C-2) := vm.closures[R(A)].fnproto(R(A+1),...,R(A+B-1)) + vm.statepos_stack.pop() + CLOSURE A Bx vm.closures.push(closure(program.functions[R(Bx)])) + R(A) := vm.closures.length - 1 CLOSE A close stack variables up to R(A) RETURN A B return R(A), R(A+1)\...,R(A+B-2) ADDF A B C R(A) := R(B) as float + R(C) as float @@ -471,8 +478,7 @@ I hope that this research will contribute to more general representations of mus # Acknowledgments -This study was supported by JSPS KAKENHI (Grant No. -JP19K21615). I would also like to thank the many anonymous reviewers. +This study was supported by JSPS KAKENHI (Grant No.23K12059). I would also like to thank the many anonymous reviewers. [^1]: The newer version of mimium compiler and VM based on the model presented in this paper is on the GitHub. diff --git a/src/main.pdf b/src/main.pdf new file mode 100644 index 0000000..83bf9e2 Binary files /dev/null and b/src/main.pdf differ diff --git a/src/main_cite.md b/src/main_cite.md index f688cc4..dc600ef 100644 --- a/src/main_cite.md +++ b/src/main_cite.md @@ -1,3 +1,7 @@ +# Lambda-mmm: the Intermediate Representation for Synchronous Signal Processing Language Based on Lambda Calculus + +Tomoya Matsuura(Tokyo Unviersity of the Arts) me@matsuuratomoya.com + ## Abstract This paper proposes $\lambda_{mmm}$, a call-by-value, simply typed lambda calculus-based intermediate representation for a music programming language that handles synchronous signal processing and introduces a virtual machine and instruction set to execute $\lambda_{mmm}$. Digital signal processing is represented by a syntax that incorporates the internal states of delay and feedback into the lambda calculus. $\lambda_{mmm}$ extends the lambda calculus, allowing users to construct generative signal processing graphs and execute them with consistent semantics. However, a challenge arises when handling higher-order functions because users must determine whether execution occurs within the global environment or during DSP execution. This issue can potentially be resolved through multi-stage computation. @@ -209,29 +213,32 @@ In the pseudocode, `R(A)` denotes the data being moved in and out of the registe In addition to Lua's upvalue operations, four new operations--- `GETSTATE`, `SETSTATE`, `SHIFTSTATE`, and `DELAY` ---have been introduced to handle the compilation of the $delay$ and $feed$ expressions in $\lambda_{mmm}$. ``` -MOVE A B R(A) := R(B) -MOVECONST A B R(A) := K(B) -GETUPVALUE A B R(A) := U(B) -SETUPVALUE A B U(B) := R(A) -GETSTATE A R(A) := SPtr[SPos] -SETSTATE A Sptr[SPos] := R(A) -SHIFTSTATE sAx SPos += sAx -DELAY A B R(A) := update_ringbuffer(SPtr[SPos],R(B)) -JMP sAx PC +=sAx -JMPIFNEG A sBx if (R(A)\<0) then PC += sBx -CALL A B C R(A),\...,R(A+C-2) := program.functions\[R(A)\](R(A+1),\...,R(A+B-1)) -CALLCLS A B C Sptr := vm.closures\[R(A)\].Sptr -    R(A),\...,R(A+C-2) := vm.closures\[R(A)\].fnproto(R(A+1),\...,R(A+B-1)) - Sptr := vm.global_sptr -CLOSURE A Bx vm.closures.push(closure(program.functions\[R(Bx)\])) R(A) := vm.closures.length - 1 -CLOSE A close stack variables up to R(A) -RETURN A B return R(A), R(A+1)\...,R(A+B-2) -ADDF A B C R(A) := R(B) as float + R(C) as float -SUBF A B C R(A) := R(B) as float - R(C) as float -MULF A B C R(A) := R(B) as float * R(C) as float -DIVF A B C R(A) := R(B) as float / R(C) as float -ADDF A B C R(A) := R(B) as int + R(C) as in -...Other basic arithmetics continues for each primitive types... + MOVE A B R(A) := R(B) + MOVECONST A B R(A) := K(B) + GETUPVALUE A B R(A) := U(B) + SETUPVALUE A B U(B) := R(A) + GETSTATE A R(A) := SPtr[SPos] * + SETSTATE A Sptr[SPos] := R(A) * + SHIFTSTATE sAx SPos += sAx * + DELAY A B C R(A) := update_ringbuffer(SPtr[SPos],R(B),R(C)) * +//*(SPos,SPtr)= vm.closures[vm.statepos_stack.top()].state +//(if vm.statepos_stack is empty, use global state storage.) + JMP sAx PC +=sAx + JMPIFNEG A sBx if (R(A)\<0) then PC += sBx + CALL A B C R(A),...,R(A+C-2) := program.functions[R(A)](R(A+1),...,R(A+B-1)) + CALLCLS A B C vm.statepos_stack.push(R(A)) +     R(A),...,R(A+C-2) := vm.closures[R(A)].fnproto(R(A+1),...,R(A+B-1)) + vm.statepos_stack.pop() + CLOSURE A Bx vm.closures.push(closure(program.functions[R(Bx)])) + R(A) := vm.closures.length - 1 + CLOSE A close stack variables up to R(A) + RETURN A B return R(A), R(A+1)\...,R(A+B-2) + ADDF A B C R(A) := R(B) as float + R(C) as float + SUBF A B C R(A) := R(B) as float - R(C) as float + MULF A B C R(A) := R(B) as float * R(C) as float + DIVF A B C R(A) := R(B) as float / R(C) as float + ADDF A B C R(A) := R(B) as int + R(C) as in +...Other basic arithmetics continues for each primitive types... ``` ### Overview of the VM Structure {#sec:vmstructure} @@ -507,8 +514,7 @@ I hope that this research will contribute to more general representations of mus ## Acknowledgments -This study was supported by JSPS KAKENHI (Grant No. -JP19K21615). I would also like to thank the many anonymous reviewers. +This study was supported by JSPS KAKENHI (Grant No.23K12059). I would also like to thank the many anonymous reviewers. ## References