Seems interesting. Since HP PPL is fast I think an alternate language that compiles to it could be very feasible, although an interpreted language would probably run as slow as 83+ BASIC or so. Just make sure, however, that the compiled code doesn't end up totally bloated or unoptimized, though.Yeah, an interpreted language isn't a good idea for speed here. Even if I made, like, a bytecode language, it wouldn't be fast.
One thing I would suggest is offering certain pre-made routines for sprites or maps, for example, with a decompressor, so that people could use different image formats that are smaller than the built-in ones. The resulting code would simply decompress the images into a GROB upon runtime.
Hello,I can see what you had to do it that way, though. Translating bytes directly into unicode would mean there would be characters like ; or control chars in the ICON. Perhaps if you encode it into base64?
>smaller than ICON (Uncompressed PNG file? There has to be a better way).
ICON is a compressed PNG... problem is that since it is in hex, it takes 2 bytes per nibble :-(
>For example, there's no simple function to get only a part of a listWhat.
yes there is! L1({5,8}) will get you elements 5 to 8 of L1 in a list..
>or to insert a list item in the middle of one.
concat(L1({1,n}), { 1, 2, 3}, L1({n,1000}))
You can also pass around functions, but they need to be properly QUOTEd to make sure that they are not evaluated at the wrong time...WHAT.
Cyrille
You can also pass around functions, but they need to be properly QUOTEd to make sure that they are not evaluated at the wrong time...Could you give an example?
EDIT: Today, I learned that a list can have a maximum of 2^31 entries! You learn something new every day.YEah I think the limit was increased in the 2nd firmware. Beforehand I think the limits from the HP 39gII were all accidentally left in, including DIMGROB size limits and stuff. IIRC the max amount of elements in lists was 999 like on the TI-83 Plus.
Hi and nice to see you again. :D
As for the new name, just keep in mind it might confuse people if they post actual source code literally :P , but I like the idea. Btw do you plan to write a tutorial on how to code in Source when finished? It might be good to post about it here if that's the case, so more people see it.
btw is this still a language written in HP PPL or does it now use ASM/C through any HP Prime exploit?
Indeed. I am really curious about how this language will look like. Just make sure it's not overly cryptic like Antidisassemblage on the 84+. Ironically, that language was meant to bridge the gap between TI-BASIC and Z80 ASM, yet it required learning ASM in order to even understand why Squirrelbox works in certain ways, which defeated the entire point.The only invented languages I know of that were successful are Axe and Nspire C++. I hope this will add another one to the list. :)
Indeed. I am really curious about how this language will look like. Just make sure it's not overly cryptic like Antidisassemblage on the 84+. Ironically, that language was meant to bridge the gap between TI-BASIC and Z80 ASM, yet it required learning ASM in order to even understand why Squirrelbox works in certain ways, which defeated the entire point.
The only invented languages I know of that were successful are Axe and Nspire C++. I hope this will add another one to the list. :)
FUNC(a)
BEGIN
MSGBOX("call "+a);
END;
FUNC2()
BEGIN
LOCAL AA=1;
LOCAL BB='FUNC(AA)';
EVAL(BB);
AA:=2;
EVAL(BB);
AA:=3;
RETURN BB;
END;
EXPORT TST2()
BEGIN
LOCAL XX=FUNC2();
LOCAL AA=4;
EVAL(XX);
END;
"1234"[n] now works to access a specific character in a string with no memory copy.
FF()
BEGIN
MSGBOX("OH MY");
END;
GLOBALVAR=FF();
I have a few ideas about how this might come in handy. ;)
Crap!
That might be quite problematic since the code gets compiled when you send it across... I'll have to check that.
Also, I think storing a char directly also does not require any memory allocations since the size isn't changing.
field x as real = 3
function test() {
x = 1 + 1
}
#pragma mode( separator(.,;) integer(h32) )
test();
x:=3;
test()
BEGIN
LOCAL TMP_1:=1;
LOCAL TMP_2:=1;
LOCAL TMP_0:=TMP_1+TMP_2;
x:=TMP_0;
END;
Ooh that is awesome :D . It seems the code gets smaller, right? How well does it get optimized for particularly complex programs?
@export
function hello() {
print("Hello, Source!")
}
#pragma mode( separator(.,;) integer(h32) )
hello();
EXPORT hello()
BEGIN
LOCAL TMP_1:="Hello, Source!";
LOCAL TMP_0:=print(TMP_1);
END;
FUNC hello [] []:
MOVS TMP_1 Hello, Source!
CALL TMP_0 print TMP_1
END
@inline
function test() {
local a = 1
return a + 1
}
@export
function hello() {
print(test()+1)
}
#pragma mode( separator(.,;) integer(h32) )
hello();
EXPORT hello()
BEGIN
LOCAL %TMP0:=1;
LOCAL a:=%TMP0;
LOCAL %TMP2:=a;
LOCAL %TMP3:=1;
LOCAL %TMP1:=%TMP2+%TMP3;
LOCAL %TMP6:=%TMP1;
LOCAL %TMP7:=1;
LOCAL %TMP5:=%TMP6+%TMP7;
LOCAL %TMP4:=print(%TMP5);
END;
@export
function hello() {
local a,b = 1,2
b,a = a,b
print(a+" "+b)
}
#pragma mode( separator(.,;) integer(h32) )
hello();
EXPORT hello()
BEGIN
LOCAL a:=1;
LOCAL b:=2;
b:=a;
a:=b;
print(a+" "+b);
END;
Nice so far. By the way at one point you should try to make an example program, such as a port of the "famed" Wacky Fun Random Numbar Generator v1.000069. Perhaps a graphical demo too to showcase the speed and size.
Nice. Would you mind pull requests in the future? :)
So how do you plan to distinguish lists from block braces? The primary reason we decided to go with the begin/end instead of { } was due to confusion and potential conflicts.
@export
function hello() {
local a,b = 1,2
a,b = b,a
print(a+" "+b)
}
#pragma mode( separator(.,;) integer(h32) )
hello();
EXPORT hello()
BEGIN
LOCAL a:=1;
LOCAL b:=2;
LOCAL %TMP2:=b;
LOCAL %TMP3:=a;
a:=%TMP2;
b:=%TMP3;
print(a+" "+b);
END;
Vectors?So how do you plan to distinguish lists from block braces? The primary reason we decided to go with the begin/end instead of { } was due to confusion and potential conflicts.
In Source, lists use [] instead. A deviance from the HPPL, sure, but one that works.
Even if I make {} the list delimiters, I believe my parsing system could handle it given some slight changes.
Vectors?
Glad to see more optimizing being done :) . Now if only ASM/C was possible on the Prime so that such program could be compiled directly on-calc or even in actual ASM code. In its current form it's still promising, though, especially considering how fast HP PPL is.Well, do DO have a way to run native code, it's just that we would have to write a LOT to get a basic framework for anything going. Actually getting reliable ASM execution is far beyond my ability, I believe.
Oh yeah I meant if somebody made the stuff required to run native code. It's possible but the question is if anybody will ever bother, considering how powerful HP PPL already is. You can already have SNES-like graphics without much slowdowns and even 3D polygons now, so if somebody decides to make a game in native code then it will most likely be a port of Doom or emulators.
And yeah glad you added If/while lol, but again I once made a game on a calculator that lacks While/For/Repeat so I guess they're not that essential, after all. :P (I had to use Lbl, Goto, IS>() and DS<())
As for Gotos I'm not a big fan of them anymore since they often cause memory leaks in certain languages or are slower, but they can be handy in some cases if you use and name them properly.
A Java exception has occured D:It was compiled in Java 8. Do you have Java 8 installed?
@export
function hello() {
@inline
local x="Source"
print("Hello, "+x)
}
#pragma mode( separator(.,;) integer(h32) )
hello();
EXPORT hello()
BEGIN
print("Hello, "+"Source");
END;
@export
function test() {
@inline
local end=10
local a,i=range(1,end),1
while i<=end {
print(a[i])
a[i]*=2
i+=1
}
print(a)
}
function list.test(a as list) {
local i = a.size()
print("The list is "~i~" elements long.")
while i>0 {
print("Element "~i~" contains "~a[i]~".")
i-=1
}
print("Interesting!")
}
@export
function main() {
local l as list = range(1,10)
l.test()
}
function types() {
local a as real //a is of type real
local b as string //b is of type string
//a = "" //real!=string, ERROR!
b = "" //string==string, fine
a = 1 //fine
//b = 1 //ERROR!
local c //c is ??, which is the base type (?) weakly typed
c = 1 //fine, c is now of type real?, again weakly typed
c = "" //fine, c is now type string?
local d = 44 //d is of type real?
a = d //real==real?, fine
//b = d //string!=real?, ERROR!
d = "" //real?==string?, fine
local e as ? //e is ?, the base type, but strongly typed
e = "" //you can set anything to e
//... But the reverse is not true.
//b = e //string!=?, ERROR!
d = e //??==?, fine
}
I still plan on buying a Prime one day. This will be one of the first programs to run on it.
Once I buy it. <_<
I'll definitively have to try Source at one point too, although since I prefer to not learn multiple languages at once I'll most likely stick to PPL at first, but if I keep running into roadblocks or can't stand it, I might attempt a switch to Source.
Anyway keep the good work on this. If this do come to fruition this is definitively front page material I'll be suggesting to staff.
@export
function powers() {
@inline
local end = 10
print("The first "~end~" powers of 2 are:")
local i,a,b = 0,0,1
while i<end {
a = a + b
b = a
print(b)
i+=1
}
print("Done!")
}
Wait, so basically if I want to make a game for both the HP Prime and the computer at once then I now can if the computer language is available for Source? O.O
That's amazing. I wonder if PC programs will run as they do on the Prime, especially for compiled languages? It would definitively make things even easier (although you would need of course good support for the TICKS and WAIT commands so we can make our games run at constant speed.Wait, so basically if I want to make a game for both the HP Prime and the computer at once then I now can if the computer language is available for Source? O.O
Yes.
Of course, Source still needs a library for drawing...
That's amazing. I wonder if PC programs will run as they do on the Prime, especially for compiled languages? It would definitively make things even easier (although you would need of course good support for the TICKS and WAIT commands so we can make our games run at constant speed.
And yeah drawing will definitively be a must, especially with how much freedom HP PPL offers already.
@export
@!optimize
function hax() {
local a="HAX"
@lang=hppl "msgbox(a)"
}
@native=MAX
function wow(a,b) {
}
@export
function getmax() {
return wow(1,2)
}
@native
function MAX(a,b) {
}
@export
function getmax() {
return MAX(1,2)
}
@export
function stuff() {
@lang=comment "This function does stuff."
print("Stuff done!")
}
I'm guessing the FFI is not going to be platform independent. Am I sensing compile-time code selection?
@export
function overloadTest() {
print(func())
print(func("an argument"));
}
function func() {
return "Got no arguments!"
}
function func(a) {
return "Got "~a
}
@main
function printTest() {
print("This ends with a newline.")
@append print("This one ")
@append print("does not.")
}
import prime.draw
import prime.io
@export
function main() {
local a = [rgb(255,0,0),rgb(0,255,0),rgb(0,0,255),rgb(255,0,255),rgb(0,255,255),rgb(255,255,0)]
screen.clear()
screen.drawString("Press any key to begin.",20,10)
waitForInput()
local i = 1
while not isKeyDown(4) {
screen.fill(a[i] as real)
screen.drawString("Source",125,40,7)
wait(.5)
i+=1
if i>a.size() {
i = 1
}
}
msgbox("Source. It's a programming language.")
}
Multiple dispatch?
import prime.draw
import prime.io
@export
function main() {
local a = [rgb(255,0,0),rgb(0,255,0),rgb(0,0,255),rgb(255,0,255),rgb(0,255,255),rgb(255,255,0)]
screen.clear()
screen.drawString("Press any key to begin.",20,10)
waitForInput()
local i = list.start
while not isKeyDown(key.esc) {
screen.fill(a[i] as int)
screen.drawString("Source",125,40,7)
wait(.5)
if a[i]==a.last() {
i = list.start
} else {
i+=1
}
}
msgbox("Source. It's a programming language.")
}
inline HP PPL support is definitively a good idea. Also if the calc ever supports ASM maybe Source could allow inline ASM opcodes?
function test[K](a as list[K]) as K {
return a[1]
}
@export
function main(a as list[int]) as int {
return test(a)
}
function do[A as int,B as int](a as A,b as B) as A {
return a+b
}
@export
function main[E as int](c as E,d as E) as E {
return do(c,d)
}
@export
function test1() {
for i in range(1,10) {
print(i)
}
}
@export
function test2() {
@downloop
for i in range(10,1,-1) {
print(i)
}
}
@export
function test3() {
local a = [5,8,7,3]
for v in a {
print(v)
}
}
@export
function test4() {
local a = [5,8,7,3]
for i,v in a.pairs() {
print(i~" "~v)
}
}
@export
function test5() {
local a = [5,8,7,3]
for newv in myOwnIter(a) {
print(newv)
}
}
iterator myOwnIter(a as list) as int {
for v in a {
return (v as int) + 1
}
}
@export
function test5() {
local a as list = [5,8,7,3]
for newv in a.myOwnIter() {
print(newv)
}
}
iterator list.myOwnIter(a as list) as int {
for v in a {
return (v as int) + 1
}
}
Can you have type parameters of a rank higher than 1? That always bugged me in Java.
Also I was always worried about For loops, because I know some languages seem to try very hard at making them weird. Even HP PPL is borderline with its FROM TO STEP DO syntax. Casio BASIC is the worst, I think, because it even inverts stuff. Instead of For(A,1,7,2) you have to write For 1->A To 7 Step 2 which is really weird.Casio Isn't that weird. They just wanted to keep the standard assignment operator for the initial part of the for loop, like in other languages where you would say something like for (int i = 0; i < n; i++). It also doesn't require another token.