Coder Social home page Coder Social logo

gabordemooij / citrine Goto Github PK

View Code? Open in Web Editor NEW
100.0 100.0 11.0 18.31 MB

Citrine Programming Language

Home Page: https://citrine-lang.org/

License: BSD 2-Clause "Simplified" License

C 96.97% Shell 0.99% Makefile 0.24% HTML 1.57% Python 0.09% Inno Setup 0.09% Java 0.05%
dutch-language french-language localization programming-language

citrine's People

Contributors

aaveshdev avatar denniscgc avatar gabordemooij avatar jadedctrl avatar janus avatar madcapjake avatar noracodes avatar shinriyo avatar takano32 avatar temurumaru avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

citrine's Issues

getting rid of magic number `40` from `ctr_build_number_from_string`

@janus says in
#28

What it the reason for using 40 instead of length.

/**
 * @internal
 * BuildNumberFromString
 */
ctr_object* ctr_build_number_from_string(char* str, ctr_size length) {
        char* numCStr;
        ctr_object* numberObject = ctr_internal_create_object(CTR_OBJECT_TYPE_OTNUMBER);
        /* turn string into a C-string before feeding it to atof */
        numCStr = (char*) calloc(40, sizeof(char));
        memcpy(numCStr, str, length);
        numberObject->value.nvalue = atof(numCStr);
        numberObject->link = CtrStdNumber;
        return numberObject;
}

This issue is re-issued above issue with pretty format.

Unit tests run out of order

On Ubuntu 17.01 running in VirtualBox in a freshly cloned copy of master,
the unit tests run in an undefined order
See the attached log.
test.log

Serialising AST header

Please could you explain to me the reason behind serializing the header. It still floating above my head.

Add support for Glyph clusters

Some groups of characters are to be counted as 1. Need some kind of engine/lib to take care of this or make it configurable at least.

String interpolation doesn't work at the end of string

catcall := 'meow'.
Pen write: 'The cat goes $$catcall'.

Crashes with this bug:

Parse error, unexpected ( ( t/020-get.ctr: 20 )
Expected ).

Actually, sometimes it seems to segfault instead of printing that error.

Not sure if this is related but the line number doesn't match too.

Noticed a repetition below..

The string "new" called twice any special reason for this. When I commented one out my code still works.

ctr_internal_create_func(CtrStdObject, ctr_build_string("new", 3), &ctr_object_make); ctr_internal_create_func(CtrStdObject, ctr_build_string("equals:", 7), &ctr_object_equals); ctr_internal_create_func(CtrStdObject, ctr_build_string("=",1), &ctr_object_equals); ctr_internal_create_func(CtrStdObject, ctr_build_string("on:do:", 6), &ctr_object_on_do); ctr_internal_create_func(CtrStdObject, ctr_build_string("respondTo:", 10), &ctr_object_respond); ctr_internal_create_func(CtrStdObject, ctr_build_string("respondTo:with:", 15), &ctr_object_respond); ctr_internal_create_func(CtrStdObject, ctr_build_string("respondTo:with:and:", 19), &ctr_object_respond); ctr_internal_create_func(CtrStdObject, ctr_build_string("type", 4), &ctr_object_type); /*ctr_internal_create_func(CtrStdObject, ctr_build_string("new", 3), &ctr_object_make);*/ ctr_internal_create_func(CtrStdObject, ctr_build_string("isNil", 5), &ctr_object_is_nil); ctr_internal_create_func(CtrStdObject, ctr_build_string("myself", 6), &ctr_object_myself); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Object", 6), CtrStdObject, 0);

`ctr_build_string function` needs some works for test 48

I checked that function and I started wondering why it does not free the argument string after memcpy. This looks strange and I tried to free , I got error while on test 48. I am still a bit confuse while C string after converting it to citrine object would still be active and live in subsequent code. And I am not able to figure out much from test 48, please explain it a bit for me.

Segfault on argument index out of range.

If, say Command argCount is 3, Command argument: 3 causes a segfault. This is the expected behavior, but it might be nice to change it as part of version 0.6 error handling.

ctr_build_string_from_cstring

I noticed sentinel '\0' in some places .... Are they not redundant?
ctr_build_string_from_cstring("Boolean\0");
ctr_build_string_from_cstring("Expected on: argument to be of type string.")

n times: not working

I have a program

3 times: {\ Pen write: 'Test.'.}.

Which, when run with the ctr, produces no output. Am I doing something wrong, or is the times: functionality not implemented yet?

ctr_object* ctr_string_html_escape

I looked at the above function and I started thinking that calling realloc when we have not exhausted memory block already created by calling malloc is not efficient in time . I think this algorithm should be made to be a bit faster by either calling **realloc ** after we have exhausted the memory block already created by malloc or while mallocing set the required memory size to be more than the actual string length to start with. If this view is accepted I will send a patch thereafter.
Finally, after calling malloc I would expect that we should check if there is enough memory or not before proceeding. This is lacking.

So cleaning needed

@gabordemooij

Thanks for this great source code, I was able to get the basic idea. It is cleanly written and in a natural way. However, the code below looks great but I was thinking that it would be great to fail fast by having the IF statement before memcpy function.

void ctr_serializer_serialize(ctr_tnode* t) {
FILE f;
f = fopen(ctr_mode_compile_save_as,"wb");
memcpy( ctr_malloc_chunk, ctr_default_header, sizeof(ctr_ast_header));/
append to addressbook, new header */
if (!f) { printf("Unable to open file!"); exit(1); }
fwrite(ctr_malloc_chunk, sizeof(char), ctr_malloc_measured_size_code+ctr_malloc_measured_size_addressbook, f);
fclose(f);
}

test119

Noticed this error while running nightly. Looks like the last test119 is having issue with my versio

EXPECTED:
search=table&restaurant=pizzaria&menu=spaghetti&menu=macaroni&course[main]=canneloni&course[dessert]=tiramisu I was looking for a free table in a pizzaria, but the waiter told me all tables have been corrupted by spaghetti, macaroni and canneloni code.

BUT GOT:
search=table&restaurant=pizzaria&menu=spaghetti&menu=macaroni&course[main]=canneloni&course[dessert]=tiramisu Error, key not found: [Request].

Test 67 fails sometimes

might be memory issue/leak,
sometimes lastIndexOf returns 9 instead of 5. please research...

Use arc4random() instead of rand()

OpenBSD uses a much safe and cryporgraphically secure randomization technique.
This feature is to make sure both Linux and OpenBSD can benefit from this technology when scripting in Citrine.

http://man.openbsd.org/arc4random.3

Linux user can install the required dependency using:

sudo apt-get install libbsd0 libbsd-dev

ctr_build_number_from_string

What it the reason for using 40 instead of length.

ctr_object* ctr_build_number_from_string(char* str, ctr_size length) {
    char* numCStr;
    ctr_object* numberObject = ctr_internal_create_object(CTR_OBJECT_TYPE_OTNUMBER);
    /* turn string into a C-string before feeding it to atof */
    numCStr = (char*) calloc(40, sizeof(char));
    memcpy(numCStr, str, length);
    numberObject->value.nvalue =  atof(numCStr);
    numberObject->link = CtrStdNumber;
    free(numCStr);
    return numberObject;
}

Citrine gammar

I am drive to understand citrine parser, I reproduced the grammar. However, I missed out a couple of things like block does not have parameters(someone here should help me figure this out). And I would like to hear your view and comments.

program ::-> statement dot {statement}
statement ::-> expression| return_token return | end
end ::-> endofprogram
return ::-> expression
expression ::-> receiver re_object
re_object ::->  assignment_token assignment| messages
assignment ::->  expression
receiver ::->  nil |  true |  false | number | string | ref | block | popen
ref ::-> [my_ref | var_ref ] name
block ::-> "{" { ref } "|" block_main "." "}" 
block_main ::-> return_token expression | expression
popen ::-> expression ")"
messages ::->  [REF | CHAIN ] message messages | empty
message ::->  bin expression | colon expression {expression} | unary_message
unary_message ::-> name
nil ::-> nil_object
true ::-> true_object
false ::-> false_object
string ::-> string_object
number ::-> number_object
block ::-> block_object
my_ref ::-> "my" 
var_ref ::-> "var" 
popen ::-> "(" expression ")"
assignment_token ::-> ":="
return_token ::-> "^"
bin ::-> "+"|"-"|"/"|"*"|"<"|">"|"=" 
colon ::-> ":"
dot ::-> "."
name ::-> [A-Za-z][A-Za-z]*

Error building on macOS

I ran into a problem while trying to build on macOS High Sierra. When running ./mk.sh I get the following:

using Linux Makefile.
rm -rf siphash.o utf8.o memory.o util.o base.o collections.o file.o system.o world.o lexer.o parser.o walker.o translator.o citrine.o ctr
cc -mtune=native -Wall -D forLinux -DlangUS -c siphash.c
cc -mtune=native -Wall -D forLinux -DlangUS -c utf8.c
cc -mtune=native -Wall -D forLinux -DlangUS -c memory.c
cc -mtune=native -Wall -D forLinux -DlangUS -c util.c
cc -mtune=native -Wall -D forLinux -DlangUS -c base.c
base.c:19:10: fatal error: 'bsd/stdlib.h' file not found
#include <bsd/stdlib.h>
         ^~~~~~~~~~~~~~
1 error generated.
make: *** [base.o] Error 1
./mk.sh: line 20: ./ctr: No such file or directory
./mk.sh: line 21: ./ctr: No such file or directory
./mk.sh: line 22: ./ctr: No such file or directory
rm -rf siphash.o utf8.o memory.o util.o base.o collections.o file.o system.o world.o lexer.o parser.o walker.o translator.o citrine.o ctrnl
cc -mtune=native -Wall -DforLinux -DlangNL -c siphash.c
cc -mtune=native -Wall -DforLinux -DlangNL -c utf8.c
cc -mtune=native -Wall -DforLinux -DlangNL -c memory.c
cc -mtune=native -Wall -DforLinux -DlangNL -c util.c
cc -mtune=native -Wall -DforLinux -DlangNL -c base.c
base.c:19:10: fatal error: 'bsd/stdlib.h' file not found
#include <bsd/stdlib.h>
         ^~~~~~~~~~~~~~
1 error generated.
make: *** [base.o] Error 1

I was able to get it to build successfully by modifying line 6, changing it from

if [ "$OS" = "OpenBSD" -o "$OS" = "FreeBSD" ]; then

to

if [ "$OS" = "OpenBSD" -o "$OS" = "FreeBSD" -o "$OS" = "Darwin" ]; then

Removed redundant object

It seems to me that variable argument2 is redundant.
ctr_object* ctr_string_skip(ctr_object* myself, ctr_argument* argumentList) {
ctr_argument* argument1;
/* ctr_argument* argument2; _/
if (myself->value.svalue->vlen < argumentList->object->value.nvalue) return ctr_build_string("",0);
argument1 = CTR_CREATE_ARGUMENT();
/_argument2 = CTR_CREATE_ARGUMENT(); _/
argument1->object = argumentList->object;
/_argument1->next = argument2; _/
/_argument2->object */
argument1->next->object = ctr_build_number_from_float(myself->value.svalue->vlen - argumentList->object->value.nvalue);
return ctr_string_from_length(myself, argument1);
}

Unexpected behaviour with "learn" message and inheritance.

Using learn to define an alias for some message on an object a causes objects that inherit from a to call the parent's definition of that behaviour when the alias is used rather than its own.

For example, after Object learn: 'is nil' means: 'Nil?', Nil is nil calls Object Nil? (returning False) instead of the expected Nil Nil? (which would return True).

Or, for another example, the following code prints False.

☞ Thing := Object new.
Thing on: 'number' do: { ↲ 2. }.

Object learn: 'to number' means: 'number'.

✎ write: (Thing new number) = (Thing new to number).

Idea for Threading/concurrency API

Given the ability to easily pass around executable code, I would think a threading API would be relatively easy to implement (or, at least, to conceptualize; I don't know much about threading in C.)

For example:

myThread := Thread new.
myThread on: 'start:' do: { number |
    Pen write: number, write: "Doing work...", brk.
    me yield.
    Pen write: number, write: "Doing more work...", brk.
}
var myThread01 := myThread new.
var myThread02 := myThread new.
myThread01 start: 1.
myThread02 start: 2.

The other option, as I see it, is to have each Thread or inherited object spawn a new thread when the message start is past, in effect acting as a thread factory.

Thoughts?

Recipe for target 'install' failed

When attempting to run make install when setting up citrine, it fails after attempting the cp ./ctr /usr/bin/ctr step, due to cp failing with the message cp: cannot stat './ctr': No such file or directory.

It does successfully create the binaries in the respective bin/"$OS" folder, so it's not a major issue, but still.

I'm running the command from the repository's root folder (the one containing the makefile), and I'm running Ubuntu 18.04 through WSL on Windows 10 - $OS and $ISO are unset by default, so I've tried running with those manually set to various values and successfully built for all combinations of (Linux/OpenBSD) and (us/nl/ro) I've tried, apart from that final cp step which always fails (even when running as root).

tests/test0216.ctr

tests/test0216.ctr
‘SINGLE_LANGUAGE’.
Program tidiness: 0.
Program memory: 180000000.
☞ a ≔ Map new.
a property: a.
✎ write: a, stop.

Socket functionality

Should socket functionality be implemented in the language, since POSIX allow it to work in basically the same way across UNIX systems, or should it be a plugin? If it should be built in, could I have some pointers on how to create new built in objects? Thanks.

Calling ctr_dparse_parse functions almost back to back

I just noticed this statement "program = ctr_dparse_parse(prg);" used two times... within a block and the first call's result not used. Any reason for this?
int main(int argc, char* argv[]) {
char* prg;
ctr_tnode* program;
ctr_argc = argc;
ctr_argv = argv;
ctr_malloc_chunk_pointer = 0;
ctr_mode_compile = 0;
ctr_mode_load = 0;
ctr_cli_read_args(argc, argv);
if (ctr_mode_compile) {
prg = ctr_internal_readf(ctr_mode_input_file);
ctr_malloc_mode = 0;
ctr_malloc_measured_size_addressbook = sizeof(ctr_ast_header);/* adds up to normal addressbook size */
program = ctr_dparse_parse(prg);
program = NULL;
ctr_malloc_mode = 1;
ctr_malloc_chunk_pointer = 0;
ctr_malloc_chunk = 0;
program = ctr_dparse_parse(prg);
ctr_serializer_serialize(program);
free(ctr_malloc_chunk);
free(prg);
exit(0);
}

[Proposal] String Interpolation

String interpolation is an awesome feature a lot of morden languages implement. I really enjoy using it and I think it makes code easier to read. Basically, it looks like this:

Pen write: 'Welcome #{name}'.

The syntax shown above is Ruby's, ES6 uses a slightly different style:

Pen write: 'Welcome ${name}'.

Syntax is debatable of course, my question is whether it should be implemented. Yay or nay?

diagonal movement never arrives at destination

☞ media ≔ Media new.
☞ plane ≔ Image new: ‘plane1.png’.

plane on: ‘destination:’ do: {
(⛏ x? > 100) yes: {
⛏ move to x: 100 y: 300.
⛏ image: ‘plane1b.png’.
}, else: {
⛏ move to x: 400 y: 350.
}.
}.

media on: ‘start’ do: {
plane x: 100 y: 300,
move to x: 400 y: 300,
speed: 1.

}.

media screen: ‘bg.png’.

Create own console

Original: On Windows: prevent console from opening on running example

This is because of how Windows implements popen() which is used in "Program command:".
Probably need to implement an alternative for Windows and re-route STDIN and STDERR.

Turns out this is more a feature than a bug: i.e. having an own console.
Because if we hide the console you cannot use the basic write functions anymore.
So rule should be:

  • If Media Plugin then:
  • Hide console
  • If write/ask/flush/stop (during Media Plugin) then open own console
  • Close own console if app quits

Harfbuzz support

To support language that require sharping, like Hindi or Arabic, we need to support the Harfbuzz engine. This is supported by SDL but we need to compile against a later version to enable FontScripts.

Failed to compile from source

It have been a long while since I played around with citrine, but today I updated my local repo and ran ./mk.bash. However, it didn't produce the expected result. Instead I got the below:

using Linux Makefile.
gcc -mtune=native -Wall -c siphash.c
gcc -mtune=native -Wall -c utf8.c
gcc -mtune=native -Wall -c memory.c
gcc -mtune=native -Wall -c util.c
gcc -mtune=native -Wall -c base.c
gcc -mtune=native -Wall -c collections.c
gcc -mtune=native -Wall -c file.c
gcc -mtune=native -Wall -c system.c
gcc -mtune=native -Wall -c world.c
world.c: In function ‘ctr_internal_object_delete_property’:
world.c:142:15: warning: variable ‘oldMapItem’ set but not used [-Wunused-but-set-variable]
ctr_mapitem* oldMapItem;
^
gcc -mtune=native -Wall -c lexer.c
lexer.c: In function ‘ctr_clex_emit_error’:
lexer.c:70:2: warning: format not a string literal and no format arguments [-Wformat-security]
printf( message );
^
gcc -mtune=native -Wall -c parser.c
parser.c: In function ‘ctr_cparse_emit_error_unexpected’:
parser.c:25:2: warning: format not a string literal and no format arguments [-Wformat-security]
printf( message );
^
parser.c:27:2: warning: format not a string literal and no format arguments [-Wformat-security]
printf( hint );
^
parser.c: In function ‘ctr_cparse_expr’:
parser.c:511:8: warning: unused variable ‘t’ [-Wunused-variable]
int t = ctr_clex_tok();
^
parser.c: In function ‘ctr_cparse_receiver’:
parser.c:467:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
gcc -mtune=native -Wall -c walker.c
gcc -mtune=native -Wall -c citrine.c
gcc siphash.o utf8.o memory.o util.o base.o collections.o file.o system.o world.o lexer.o parser.o walker.o citrine.o -rdynamic -lm -ldl -o ctr
lexer.o: In function ctr_clex_tok': lexer.c:(.text+0x71c): undefined reference toctr_clex_is_delimiter'
lexer.c:(.text+0x771): undefined reference to ctr_clex_is_delimiter' lexer.c:(.text+0x7c6): undefined reference toctr_clex_is_delimiter'
collect2: error: ld returned 1 exit status
makefile:14: recipe for target 'ctr' failed
make: *** [ctr] Error 1

citrine-lang.org landing page

Won't it be nice to show the user how to run the program. Something like "$ ctr hello.ctr"
A slightly over-engineered 'hello world' program:

Butler := Object new.
Butler on: 'greet:' do: { name |
Pen write: 'Welcome ' + name.
}.
james := Butler new.
james greet: 'visitor'.

This program will generate the following output:
Welcome visitor

mk bash and make install

I can't truly figure out the difference between ./mk.bash and make install except cp ./ctr /usr/bin/ctr and object files littering folder. Is there something I am missing?

git clone --depth=50 https://github.com/gabordemooij/citrine.git gabordemooij/citrine
cd gabordemooij/citrine
git fetch origin
git checkout -qf FETCH_HEAD
./mk.bash
make install

cgi exists already?

I read document how to write template like PHP.
But, I couldn't find how to run server.
So, cgi function does not exist yet?

Enforce pipe rules

Right now you may use \ and | to separate params in a block from the block body.
The Lexer should enforce use of \ only for blocks without any parameters and forbid the use of | for empty param sections.

Small memory leak in ctr_internal_plugin_find

The buffer realPathModName as allocated by realpath is never freed (see here)

Do you want to wait and let me fix it on my branch (it will probably take a while before that one is ready to be merged), or do you want to fix it yourself?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.