lartu / ldpl Goto Github PK
View Code? Open in Web Editor NEWCOBOL-like programming language that compiles to C++. With serious dinosaurs with neckties and briefcases π¦πΌ
Home Page: https://www.ldpl-lang.org/
License: Apache License 2.0
COBOL-like programming language that compiles to C++. With serious dinosaurs with neckties and briefcases π¦πΌ
Home Page: https://www.ldpl-lang.org/
License: Apache License 2.0
Check this and add audio playback support to the language. Maybe something like:
DATA:
myAudio IS AUDIO
PROCEDURE:
LOAD AUDIO "audio.mp3" IN myAudio
PLAY myAudio
...
PAUSE myAudio
PLAY myAudio LOOPING
...
STOP myAudio
SET VOLUME OF myAudio TO number
https://stackoverflow.com/questions/3636715/cross-platform-sound-api-for-games
When a negative number (for example -12.2
) is stored in a TEXT variable, a 0 is appended before it.
For example this:
data:
strVar is text
procedure:
store -12.989 in strVar
display strVar crlf
Displays 0-12.989
.
Add a command that must be put at the beginning of a file that determines the minimum LDPL version that can run the script.
Maybe something like REQUIRED VERSION "1.0.0"
When in LDPL you execute the statement
DISPLAY 0123
the value 83 is printed instead of 123. One would expect 123 to be printed, but this other number is printed instead because C++ asumes numerals that start with 0 (even 0 itself) to be encoded in octal base.
The same happens with vector accesses, for example if you store 1 in vector:0012, if you read vector:12 you'll find a 0, for the index that was accessed is not 12 but octal 12.
This should be fixed by checking if numerals have leading 0s and removing them (except, of course, if they are followed by a .
and decimals).
At the moment the skeleton for a COUNT statement is defined within ldpl.cpp but it's not been fully written.
if(line_like("COUNT $str-expr FROM $str-expr IN $num-var", tokens, state))
{
if(state.section_state != 2)
error("COUNT statement outside PROCEDURE section (\033[0m" + current_file + ":"+ to_string(line_num)+"\033[1;31m)");
//C Code
//TODO
return;
}
This should be completed.
Tested this on Mac and Linux, seems like the exit code is getting misreported:
$ cat report.ldpl
DATA:
code is number
PROCEDURE:
execute "sh bad.sh" and store exit code in code
display "exit code: " code crlf
$ cat bad.sh
#!/bin/sh
exit 1
$ ldpl report.ldpl
LDPL: Compiling...
* File(s) compiled successfully.
* Saved as report-bin
$ ./report-bin
exit code: 256
$ sh bad.sh
$ echo "exit code: $status"
exit code: 1
Given the following code:
DATA:
i IS NUMBER
local.min IS NUMBER
local.max IS NUMBER
PROCEDURE:
STORE 0 IN i
WHILE i IS LESS THAN argc DO
IF i IS EQUAL TO 0 THEN
STORE argv:i IN local.min
STORE argv:i IN local.max
END IF
IF argv:i IS LESS THAN local.min THEN
STORE argv:i IN local.min
END IF
IF argv:i IS GREATER THAN local.max THEN
STORE argv:i IN local.max
END IF
ADD i AND 1 IN i
REPEAT
DISPLAY "Min (" local.min ") Max (" local.max ")" CRLF
I get the Error: Malformed statement
error for line 14 being IF argv:i IS LESS THAN local.min THEN
.
If I assign argv:i
to a variable it works:
STORE argv:i IN n
IF n IS LESS THAN local.min THEN
Is this a bug or a feature?
LDPL should really support expressions. It's very cumbersome to have to use
MULTIPLY someVar BY someConstant IN temp_var
ADD initialValue TO temp_var in TEMP_var
to do initialValue + someVar * someConstant
. Given that LDPL compiles to C++, adding expressions to the language should be fairly easy. I'm not saying that IF
statements or WHILE
statements should support them (it would be nice, though), I'm saying that there should be some statement like
IN var SOLVE EXPRESSION initialValue + someVar * someConstant
There are a bunch of //TODOs in ldpl.cpp, for statements (like COUNT) programmed into the language but not coded (you can use them in your code but they won't do anything). They should be completed.
It would be nice if LDPL could work with binary data. It would probably need two things:
0b1010
) and hex (0xFF
) number literals.Maybe the commands could look like this:
BITWISE A AND B IN C
BITWISE A OR B IN C
BITWISE A XOR B IN C
BITWISE NOT A IN C
BITWISE SHIFT A LEFT BY B IN C
BITWISE SHIFT A RIGHT BY B IN C
GET BIT AT N FROM A IN C
Would this be a good candidate for the language or should it be an extension?
LDPL should tell you when there's no C++ compiler found on your path instead of just throwing a "program c++ not found" error.
https://docs.ldpl-lang.org/about-ldpl/using-the-ldpl-compiler this part is outdated compared to the readme found in this repo. The installation instructions should be copied from here.
I tried compiling a simple LDPL program on a linux-arm
machine and, while it compiled and ran, it wouldn't run on a different linux-arm
machine. I got this error:
$ ./hi-arm
./hi-arm: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./hi-arm)
Adding compile_line+=" -static-libgcc -static-libstdc++ ";
to ldpl.cpp
and rebuilding the compiler fixed it:
$ ./hi-arm
hi, arm!
However the binary size balloons from 90K to 1.5M.
Should LDPL programs be static, like the compiler itself? I think so yea?
Not sure if it's beyond the scope of this language given how its a bit tongue in cheek but it would be nice to have the ability to split a program up into components and then include them aka the COBOL INCLUDE
statement.
Given a directory structure like so:
.
βββ src
βββ main.ldpl
βββ member-name.ldpl
βββ another-member-name.ldpl
You could within the DATA
division allow an INCLUDE
statement with similar syntax to COBOL:
DATA:
INCLUDE member-name.ldpl
INCLUDE another-member-name.ldpl
Or maybe have an additional INCLUDE
division?
In either case the include could act as a "copy-paste" merging the DATA
and PROCEDURE
divisions of the included source into the requesting file in the order in which they are included.
You could go one further and allow the INCLUDE
statement in the PROCEDURE
division to open the possibility of dynamic includes ;)
In adding includes it opens this language up to the entertaining possibility of libraries.
Right now, when you import a .ldpl file into an LDPL project all the files get compiled one after another sequentially. This means that if I import file1, file2 and file3, variables in file 1 will be declared first, then its code will be compiled, then variables in file2 will be declared, etc. In the end this means that if in file1 I want to use a variable or a sup-procedure declared in file2 this will be impossible.
I think that probably the best way to fix this would be to make a big file copying all three DATA sections together and all PROCEDURE sections together and then compiling.
Hello there, @dvkt! Yesterday I added EXTERNAL SUB-PROCEDURE
to the language. Essentially it's a way to declare functions that have been forward declared in C++, so I can call LDPL functions from C++.
So in C++ I can, for example, do this:
LDPL_SUBPROCEDURE();
void myFunction(){
LDPL_VAR = 18;
LDPL_SUBPROCEDURE();
}
And in LDPL I do:
data:
ldpl-var is external number
procedure:
external sub-procedure ldpl/subprocedure
display "My number is " ldpl-var
end sub-procedure
I want to know what do you think about this. I made an IRC bot library for LDPL that I'll be uploading today and I needed this for that to work.
Looking at the source code there seems to be a mix of conventions, particularly in src/ldpl.cpp
about indentation, brace placement, naming, etc.
While probably not a high priority issue, having standard guidelines to follow or having a .clang-format
that could be run would be useful to contributors.
Interpreter flags like -i and -r should be documented properly.
When you write
STORE myNumberVar IN myTextVar
the resulting value has a lot of trailing zeros. This should be fixed.
A set of tests should be designed and setup along with a test script to test each new commit made to ldpl without much effort.
Some way to SLEEP the program for N seconds would be nice.
Hey @dvkt! Could you please -when you have the time, no rush- compile a macOS binary for LDPL 3.0.0 and upload it to the release? For a major release like this one, I'd be nice to have a binary for each major operating system and unfortunately I don't have a Mac made in the last ten years.
Thanks!
At the moment the skeleton for a GET INDEX OF statement is defined within ldpl.cpp but it's not been fully written.
if(line_like("GET INDEX OF $str-expr FROM $str-expr IN $num-var", tokens, state))
{
if(state.section_state != 2)
error("GET INDEX OF statement outside PROCEDURE section (\033[0m" + current_file + ":"+ to_string(line_num)+"\033[1;31m)");
//C Code
//TODO
return;
}
This should be completed.
What do you think about an EMPTY VECTOR vec
command that clears the content of a vector?
I am splitting apart string into vectors in a loop, and right now I'm clearing the vector by hand. Maybe that's okay though?
I added the -f flags to the compiler. You can use -f= to pass to the C++ compler (you could use -i too, I guess, but having both makes things clearer for me). I should document how it works.
These new functions have been added to the language. I would document them now, but it's quite late and I've gotta hit the sack. If someone wants to document them, you are more than welcome to do so. If not, I'll get to it soon.
@dvkt I think that on this commit, Windows hability to compile static binaries was broken. Since you added the __linux__
check, do you by any chance know what the Windows equivalent would be?
Thank you!
Hey @dvkt I've found this:
bool is_label(string & token){
return !isdigit(token[0]) && token[0] != ':' && token[0] != '"';
}
Why can't labels be numbers or start with : or be strings? Any particular reasons?
@dvkt has made a wonderful contribution to the language and it should be added to the standard. The website should also be pushed to a separate repository.
Maybe the seed is constant by accident? I get the same results each time, it seems:
$ cat rand.ldpl
DATA:
r is number
i is number
PROCEDURE:
while i is less than 5 do
store random in r
display r crlf
incr i
repeat
$ for i in {1..5}; do echo "# ${i}"; ./rand-bin; done
# 1
0.365382414946976
0.982248013830859
0.642368455250919
0.28662740219693
0.346748723809956
# 2
0.365382414946976
0.982248013830859
0.642368455250919
0.28662740219693
0.346748723809956
# 3
0.365382414946976
0.982248013830859
0.642368455250919
0.28662740219693
0.346748723809956
# 4
0.365382414946976
0.982248013830859
0.642368455250919
0.28662740219693
0.346748723809956
# 5
0.365382414946976
0.982248013830859
0.642368455250919
0.28662740219693
0.346748723809956
For some reason the 'compiled on' date displayed by the ldpl
executable is behind by exactly one day.
Steps to reproduce the issue:
~/code/ldpl[master]$ date
Tue Mar 19 13:58:42 EDT 2019
~/code/ldpl[master]$ cd src
~/code/ldpl/src[master]$ make
g++ -g ldpl.o -o ldpl -static-libgcc -static-libstdc++
~/code/ldpl/src[master]$ ldpl --version
This is LDPL 19 version 2.1.1
Copyright 2018-2019, MartΓn del RΓo
Standard and documentation can be found on ldpl.lartu.net.
Source code can be found at https://github.com/lartu/ldpl.
LDPL may be copied only under the terms of the GNU General Public License 3.0.
Compiled on Mon Mar 18 14:53:28 EDT 2019
Information about the machine the error occured on:
~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.6 LTS
Release: 16.04
Codename: xenial
~$ uname -a
Linux vsc 4.15.0-45-generic #48~16.04.1-Ubuntu SMP Tue Jan 29 18:03:48 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Normally in LDPL, text variables are by default initialized to "", the empty string. I've just noticed this is not the case with vectors. If you declare a text vector and then access a non-initialized index, the value stored there will be 0. No "0", but 0. This has to do with how LDPL declares and stores variables. Long story short, when text variables are declared, they are assigned the value of "" by default. When vectors are initialized, no values are assigned, you can't assign a value to every possible subindex of the vector, so when you try to access an uninitialized index you get the default value for an uninitialized variable in LDPL, that is 0.
This will be fixed soon as it is not the intended behavior of this data structure.
Explanation:
In the LDPL Test Battery we write LDPL code tests to test the language. We require some tests for the GET INDEX OF
, COUNT
, SUBSTRING
and TRIM
statements of the language, as well as for the LIST
data type. Any help with any of these would be greatly appreciated.
The spec says STORE NUMBER-VAR or NUMBER or TEXT-VAR or TEXT IN NUMBER-VAR or TEXT-VAR
so vectors are not included. Are the plans to keep it that way?
I get LDPL Error: Malformed statement (copy-v.lsc:9)
when running this program:
DATA:
v1 is text vector
v2 is text vector
PROCEDURE:
store "En" in v1:0
store "To" in v1:1
store v1 in v2
Due to popular request, GOTO should be added to the language.
Right now, when you use LOAD FILE
and the file can't be loaded, the whole program is closed. This shouldn't happen.
Identifier Naming Schemes doesn't say anything about numbers as identifiers.
Number vector sub-indexes are converted to strings using std::to_string, leading to odd behavior.
For example, this example displays "dinosaurio" and then "dragΓ³n" because 0 is converted to "0.000000", but the reference doesn't suggest this behavior.
Right now, LDPL has one control variable, FILE-LOADED
, that's used by the language to tell whether a file has been loaded right or not. That's a little specific, as many other statements could also benefit from having a control variable to check if they executed correctly or not. This variable should be replaced with two other variables, ERROR-CODE
, that should store an error number regarding the result of the operation, and ERROR-TEXT
that should store a human readable report of what went wrong (or not).
FILE-LOADED
is declared here and used here. At the moment no other function than LOAD FILE
uses it, but WRITE TO
, APPEND TO
, numeric ACCEPT
and type conversions should use it as well.
I don't think there's a way to get ENV variables in LDPL currently, right?
If not, they could either be pre-set like argv
and argc
, or there could be a new statement like STORE ENV AT "PATH" IN $path
to do a lookup.
The language needs portable file operations, as using EXECUTE along with cat and echo (or whatever) is not portable to windows.
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.