digego / extempore Goto Github PK
View Code? Open in Web Editor NEWA cyber-physical programming environment
A cyber-physical programming environment
If I try and pass an i64
as an argument and the compiler doesn't have enough information to infer the types
(bind-func test
(lambda (a)
(let ((i 0))
(dotimes (i a)
(printf "i = %lld\n" i)))))
I get the error message
Compiler Error: bad floating point type 0 required: 0
When I add a type annotation to a
it all works fine
(bind-func test
(lambda (a:i64)
(let ((i 0))
(dotimes (i a)
(printf "i = %lld\n" i)))))
;; this now compiles & works fine
(test 10)
Why does the error message mention a bad floating point type?
afill!
is being naughty and allowing me to write beyond the end of an array
(bind-func test
(lambda ()
(let ((a:|2,double|* (alloc)))
(afill! a 0.0 1.0 2.0)
(printf "result = %f\n" (aref a 2)))))
(test) ; prints 'result = 2.000000'
If one of the (optional) additional 2nd arguments (such as a memzone size or a docstring) is on the same line as the bind-func
, then the indenting doesn't work properly (same as in issue #35).
particularly audio and each individual extempore process.
There's something weird going on when I try and mix assigning integer and float literals in a let
These two do compile
(bind-func test
(lambda ()
(let ((i 0.0)
(j 0.0))
0.0)))
(bind-func test
(lambda ()
(let ((i 0)
(j 0))
0.0)))
These two throw a could not resolve types: "j" error
(bind-func test
(lambda ()
(let ((i 0)
(j 0.0))
0.0)))
(bind-func test
(lambda ()
(let ((i 0.0)
(j 0))
0.0)))
This would help people who prefer to manage their elisp packages through package.el
and el-get
I'm defining a new type, say
(bind-type ben-type <i64>)
and I define an xtlang function which takes an argument of that type
(bind-func reset-ben-type
(lambda (bt:ben-type*)
(tset! bt 0 0)
bt))
If I try and call that function from scheme (with any type of arguments)
(reset-ben-type 5)
then extempore crashes with the error message
terminate called throwing an exception[1] 72532 abort ./extempore --device 2
If I try and make my own type, for example:
(bind-type ben-type <double>)
that seems to work ok, but when I try and use the new type
(bind-func test
(lambda (a:ben-type)
0.0))
I get an error:
There is no scheme stub available for "test"
I'm using a tuple and setting it's values with tset!
. This works as normal:
(bind-func test
(lambda ()
(let ((tup:<i64,i64>* (salloc)))
(tset! tup 0 42)
(printf "tuple[0]:%d\n" (tref tup 0)))))
(test)
When I pass additional arguments to tset!
, though
(bind-func test
(lambda ()
(let ((tup:<i64,i64>* (salloc)))
(tset! tup 0 42 1.5 "foo")
(printf "tuple[0]:%d\n" (tref tup 0)))))
(test)
There are no errors, and the value still gets set properly. Should the compiler kick up a stink, or is that behaviour deliberate?
If you accidentally use two colons instead of one when trying to bind a value with a type, e.g.
(bind-func test
(lambda ()
(let ((a::i64 0))
0.0)))
then instead of giving a compiler error I get a scheme backtrace, which is a bit confusing.
If I have a toplevel xtlang function
(bind-func arg_test
(lambda (a:i64)
(printf "a = %lld\n" a)
a))
(arg_test) ;; prints a = 0
that is, if there aren't enough args passed in it just blazes ahead anyway.
Similarly, if I pass too many args, then the extra ones get ignored
(arg_test 3 6) ; prints a = 3
emacs mode does not respect comments - still highlighting symbols in comment
If the symbol test
is unbound, then trying
(println test)
gives
Eval error: not valid dot syntax
position:(10) in function "toplevel"
eval: unbound variable:
with: test
Trace:
instead of a more descriptive and helpful error message.
in xtlang functions the 'less/greater than or equal to' operators (<=
/>=
)seem to be missing:
(bind-func test
(lambda ()
(if (<= 1 2)
(printf "true!\n")
(printf "false!"))))
throws Compiler Error: unbound symbol: <=
returning after dotimes indents the following line incorrectly:
(dotimes (i 10)
(body))
should be
(dotimes (i 10)
(body))
I'm trying to use polymorphism via bind-poly
, and it's having trouble with type inferencing.
(bind-func test-a
(lambda (a:i32)
a))
(bind-func test-b
(lambda (b:i64)
b))
(bind-poly test test-a)
(bind-poly test test-b)
(bind-func run-tests
(lambda ()
(let ((arg 0))
(test arg))))
In this example, run-tests
won't compile, giving the error:
Compiler Error: no valid polymorphic options for: (test##6 arg)
But if I specify the type of arg
, i.e.
(bind-func run-tests
(lambda ()
(let ((arg:i64 0))
(test arg))))
everything is fine. Perhaps a more descriptive error message, e.g. "poly'd function: test
types underspecified" or something?
The source code (in the extempore.el
Emacs major mode) should visually differentiate between the scheme and xtlang forms - perhaps by using different coloured parens?
Maybe all the basic arithmetic functions (+
, -
, etc.) should get font-locked like functions anyway?
be really nice to add a status bar at the top of an extempore buffer (like erc-mode) for extempore related information - things like contextual help for function signatures and the like.
Extempore won't let me 'shadow' variables—fair enough. But in this case:
(bind-func test
(let ((a:i64 0)
(b:i64 1))
(lambda (a:i64)
(* a 2))))
The argument to the function a
shadows the a
in the let, which is the source of the problem. However, if there is another binding in the let (in this case b
), then the error message incorrectly says that b
is the problem:
Compiler Error: Sorry single definition variables only! caught trying to redefine "b" as a shadow variable
If I have a let
with no expressions in the body
(bind-func inf-test
(lambda (a:double*)
(let ((i 0)
(k 0)
(y 0))
)
a))
I get a weird error:
position:(0) in function "impc:ti:mark-returns"
function(car): argument 1 must be: pair
argument values:
with: #<PROC car>
Trace: impc:ti:mark-returns <- map <- impc:ti:mark-returns <- map <- impc:ti:mark-returns <- impc:ti:run <- impc:ti:parametric-poly-pass
What's the go with that?
I get this error when I try to compile Extempore on OS X 10.6 / x86.
src/Extempore.cpp:150: error: ‘printDevices’ is not a member of ‘extemp::AudioDevice’
a null input audio device causes crash on windows
It would be great if Emacs could pop up (in the minibuffer) the argument list for any function as you type - similar to the way that eldoc
does.
If I don't give modulo
enough arguments, instead of printing the nice 'bad arity' error message I just get a scheme backtrace from the compiler. E.g.
(bind-func test
(lambda ()
(modulo 7)))
There seems to be a mistake in README.md
$ cd /path/to/extempore/lib/AsmParser
$ patch < /path/to/extempore/extras/llparser.patch
Shouldn't the first path refer to LLVM source directory?
If I try and bind-poly a function closure which hasn't been defined yet, I get a scheme backtrace from the compiler rather than a nice error.
(bind-poly test test-a)
gives
position:(0) in function "caar"
function(car): argument 1 must be: pair
argument values:
with: #<PROC car>
Trace: caar <- unzip1-with-cdr-iterative <- map <- impc:ir:get-function-type
set!
doesn't work when trying to set tuples, even if they are the appropriate type. The function below compiles, but b
isn't updated by the call to set!
(bind-func test
(lambda ()
(let ((b:<i32,i32>* (salloc))
(c:<i32,i32>* (salloc)))
(tfill! b 236 23425)
(tfill! c 2 2)
;; should be able to set pointer b to pointer c
(set! b c)
(printf "%d %d\n" (tref b 0) (tref b 1))
)))
(test)
In a let
, any variable bound after a lambda
will cause an error if you try and use that variable. So this fails (because the variable b
is bound after the lmb
in the let
)
(bind-func test1
(lambda ()
(let ((lmb:[i64,i64]* (lambda (a) (* a 2)))
(b 3))
(* b 1))))
but this works.
(bind-func test2
(lambda ()
(let ((b 3)
(lmb:[i64,i64]* (lambda (a) (* a 2))))
(* b 1))))
I want to define a type alias that contains another type alias:
(bind-alias ben-alias double)
(bind-alias ben-alias2 <ben-alias,ben-alias>)
(bind-func test1
(lambda (a:ben-alias)
0.0))
(bind-func test2
(lambda (a:ben-alias2)
0.0))
test1
compiles and works fine, but when I try and compile test2
, the first time I get an error:
There is no scheme stub available for "test2"
and any subsequent times I try and evaluate test2
I get a different error:
Compiler Error: Internal error impc:ir:get-type-from-str must take a string not ""
If compound aliases aren't allowed, then I guess it should at least give a more informative error message.
need midi i/o support. preferably through external lib.
bind-val
doesn't work if the symbol starts with a number (e.g. 2pi
), but it's a bit deceptive because it prints a 'success' message to the log and only fails when you try and reference the value in an xtlang function
If I bind-val
a small array, it works fine, e.g.
(bind-val arr1 |10,double| 1.0) ; works fine
but if the size of the array gets larger than N (from my testing it seems that N ~ 20000), e.g.
(bind-val arr2 |30000,double| 0.0) ; crashes extempore
extempore prints ALLOCATED NEW MEMORY: new_total(499903)
a whole bunch of times before crashing with the message:
VERY VERY BAD - Bottom and Top met in insert_treadmill !!!!!!!
ALLOCATED NEW MEMORY: new_total(499899)
Out of memory!!. Catastrophic error!! free cells: 0
I guess it's not a bug per se—when you try and grab too much memory all bets are off. But an array of 30000 doubles should only be about 2MB. What is the magic number for how big is too big?
This code throws a compile error:
(bind-func test
(let ((i 0))
(dotimes (i 3)
(if (> i 1) 1.0 2.0)
(printf "i = %d\n" i))
(lambda ()
0.0)))
But if the if
line (in the dotimes
) is commented out, the function compiles (and prints the values of i
) as expected.
Currently, if I bind a global variable
(bind-val g-var-a i32 5)
then I can increment it in a closure as expected
(bind-func my-test
(lambda (inc)
(set! g-var-a (+ g-var-a inc))
g-var-a))
(println (my-test 3)) ;; prints 8
but if I re-evaluate the first (bind-val)
expression the compiler says it's bound successfully, but the incrementing value is not reset.
So I was messing around with making envelopes, and I ended up using the symbol make-env
. Instead of a regular compile error, I got a scheme backtrace from the xtlang compiler.
Looking at runtime/llvmti.xtm
, It looks like I accidentally stumbled across a symbol defined deep in the compiler. Is it worth giving those symbols some sort of prefix to prevent that happening? Or should I just avoid make-env
?
It would be great if the extempore executable would look on startup to see if an .xtmprofile
existed in the working directory.
This could be used for setting devices/device options and other settings on a per-project basis.
thinking of adding pptr[0]
, aptr|0|
and tptr<0>
for pref
and tref
indexing? We could also think about ptr[0]=
for pref-set
etc..
we still need these to be unique at the moment to help out the type inferencer (i.e. we can't use []
for everything unfortunately).
this would be pure syntactic sugar at this stage - i.e. first-transform.
Through top-level scheme calls, I can set param values associated with xtlang closures
(bind-alias DSP [double,double,double,double,double*]*)
(bind-func dsp:DSP 1000000
(let ((delay-buffer:|88200,double|* (zone-alloc))
(delay-time 100)
(decay 0.9))
(lambda (in time chan data)
(let ((samp-ref (+ (dtoi64 chan)
(* 2
(modulo (dtoi64 time)
delay-time))))
(value (if (> (random) 0.9999)
0.6
0.0)))
(aset! delay-buffer
samp-ref
(+ value (* decay (aref delay-buffer
samp-ref))))
(aref delay-buffer samp-ref)))))
; set the delay time here
(dsp.delay-time 30)
But if I try and just read the value of the param (i.e. (dsp.delay-time)
), the whole thing segfaults - oops!
;; this should give a better error for the line (+ a b)
(bind-func bad-func
(let ((a:float* (alloc 1)))
(lambda (b:float)
(pset! a 0 5.5)
(+ a b))))
(bind-func good-func
It would default to 0
;; this should give a better error for the line (+ a b)
(bind-func bad-func
(let ((a:float* (alloc 1)))
(lambda (b:float)
(pset! a 0 5.5)
(+ a b))))
(bind-func good-func
(let ((a:float* (alloc 1)))
(lambda (b:float)
(pset! a 0 5.5)
(+ (pref a 0) b))))
final bar of array type is not highlighting
This should return a useful compiler error
(bind-func castbug
(lambda (a:i8_)
(case a i32_)))
it would be nice to be able to "eval" a single expression to multiple machines. in other words, it would be nice to be able to extempore-connect to multiple hosts/ports
this line
bat jam --build-dir=
toodset=msvc link=static address-model=64 --build-type=complete stageshould be
bjam --build-dir=
toodset=msvc link=static address-model=64 variant=release --build-type=complete stageCurrently, if you try and define an xtlang
closure (i.e. use bind-func
), it won't let you have a !
in the name. The error that is thrown is a scheme backtrace from the xtlang
compiler:
position:(0) in function "impc:ti:mark-returns"
function(car): argument 1 must be: pair
argument values:
with: #<PROC car>
Trace: impc:ti:mark-returns <- map <- impc:ti:mark-returns <- impc:ti:run <- impc:ti:parametric-poly-pass
Perhaps a more informative error message would be useful?
If tfill!
is given too many arguments for a given tuple type, then the compiler throws a messy scheme error.
It would be nice to have the option to populate buffers as an alternative to sample by sample processing in the dsp callback.
Looking at the C++ code it looks like this option has already some stubs available.
This would make the following cases more intuitive
So maybe as an addition to
in:double time:double chan:double data:double*
the following signature could be supported
in:double** out:double** time:double count:uint32 data:double*
in - pointer for input buffers
out - pointer for output buffers
time - time of start
count - size of individual buffers
data - same as in the other signature
maybe also
in_buffers - number of input buffers
out_buffers - number of output buffers
count, in_buffers and out_buffers could also be environment variables
If I get the binding order wrong in a let
, e.g. trying to use the symbol len
before it is bound:
(bind-func test
(lambda ()
(let ((a:double* (alloc len))
(len 4))
0.0)))
I get a 30 line llvm dump, rather than a clear error message.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.