Coder Social home page Coder Social logo

never-lang / never Goto Github PK

View Code? Open in Web Editor NEW
430.0 19.0 8.0 2.81 MB

Never: statically typed, embeddable functional programming language.

Home Page: https://never-lang.readthedocs.io

License: MIT License

C 96.10% Yacc 2.14% Lex 1.25% CMake 0.40% Makefile 0.01% JavaScript 0.02% HTML 0.07%
programming-language functional-programming compilers virtual-machine language functional-language scripting-language compiler

never's Introduction

Never - Functional Programming Language

Version Codecov

Never is a simple functional programming language. Technically it may be classified as syntactically scoped, strongly typed, call by value, functional programming language.

In practise Never offers basic data types, assignment, control flow, arrays, first order functions and some mathematical functions to make it useful to calculate expressions. Also it demonstrates how functions can be compiled, invoked and passed as parameters or results between other functions.

Getting Started

It is easy to download and compile Never language. Just clone repository and make the compiler in a few basic steps. To read more visit readthedocs.io site.

Prerequisites

Never requires basic Linux installation to be built. The following tools and libraries are needed:

  • gcc
  • glibc
  • bison / flex
  • libmath, libdl and libffi

Installing

Never can be installed in steps:

  • clone repository
  • cd never
  • mkdir build; cd build
  • cmake ..; make

asm.js wasm

To compile for asm.js or wasm targets use the following commands:

Get the latest sdk: git clone https://github.com/emscripten-core/emsdk.git

cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh

Compile to native asm.js

mkdir build && cd build
emcmake cmake .. -DJS_ONLY=ON 
make

Compile to native wasm

mkdir build && cd build
emcmake cmake .. -DWASM_ONLY=ON 
make

Run

Now you should see never.js file in your build directory. You can overwrite ../never.js and open never.html, or modify never.html to load build/never.js file or load the file in JS console and run:

python -m SimpleHTTPServer 8000
# http://localhost:8000/never.html
var never = Module.cwrap('never','number',['string']);
never("func main() -> int { 123 }")

Contributing

All help is welcome! Using it, reporting bugs, spreading the word, writing code samples, blogs, submitting ideas, documentation, new features. Everyone is invited to contribute.

License

This project is licensed under the MIT License.

never's People

Contributors

b4yuan avatar kuba-- avatar smaludzi 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

never's Issues

never 2.1.2 build failure

๐Ÿ‘‹ it looks like there is some build issue with the 2.1.2 release, the build error log is below:

==> cmake ..
==> make
Last 15 lines from /Users/rchen/Library/Logs/Homebrew/never/02.make:
make

/usr/local/Cellar/cmake/3.21.1/bin/cmake -S/tmp/never-20210822-10267-kpy8ma/never-2.1.2 -B/tmp/never-20210822-10267-kpy8ma/never-2.1.2/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/local/Cellar/cmake/3.21.1/bin/cmake -E cmake_progress_start /tmp/never-20210822-10267-kpy8ma/never-2.1.2/build/CMakeFiles /tmp/never-20210822-10267-kpy8ma/never-2.1.2/build//CMakeFiles/progress.marks
/Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/Makefile2 all
/Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/nev.dir/build.make CMakeFiles/nev.dir/depend
[  0%] [BISON][parser] Building parser with bison 2.3
[  1%] [FLEX][scanner] Building scanner with flex 2.5.35
cd /tmp/never-20210822-10267-kpy8ma/never-2.1.2 && /usr/bin/bison -d --verbose -o /tmp/never-20210822-10267-kpy8ma/never-2.1.2/front/parser.c /tmp/never-20210822-10267-kpy8ma/never-2.1.2/front/parser.y
cd /tmp/never-20210822-10267-kpy8ma/never-2.1.2 && /usr/bin/flex -o/tmp/never-20210822-10267-kpy8ma/never-2.1.2/front/scanner.c /tmp/never-20210822-10267-kpy8ma/never-2.1.2/front/scanner.l
/tmp/never-20210822-10267-kpy8ma/never-2.1.2/front/parser.y:210.9-16: syntax error, unexpected identifier, expecting string
make[2]: *** [../front/parser.c] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [CMakeFiles/nev.dir/all] Error 2
make: *** [all] Error 2

relates to Homebrew/homebrew-core#70629

No discussion group for never-lang

I would like to discuss never-lang outside of issue reports.
Discord or Slack would work,
There would be no expectation of real time responses.

File I/O

Does Never support reading and write files? I can't seem to find anything in the documentation about this?

Make Gives Error

I did the following things:

git clone https://github.com/never-lang/never.git
mkdir build
cd build
cmake ..

Then I called make, but then it gave this error:

CMakeFiles/nev.dir/build.make:74: warning: overriding recipe for target 'parser.txt'
CMakeFiles/nev.dir/build.make:71: warning: ignoring old recipe for target 'parser.txt'
[  1%] [FLEX][scanner] Building scanner with flex 2.6.1
[  2%] [BISON][parser] Building parser with bison 3.0.4
[  3%] [BISON][parser] Copying bison verbose table to parser.txt
Scanning dependencies of target nev
CMakeFiles/nev.dir/build.make:74: warning: overriding recipe for target 'parser.txt'
CMakeFiles/nev.dir/build.make:71: warning: ignoring old recipe for target 'parser.txt'
[  3%] [BISON][parser] Building parser with bison 3.0.4
[  4%] Building C object CMakeFiles/nev.dir/front/parser.c.o
[  5%] Building C object CMakeFiles/nev.dir/front/scanner.c.o
[  6%] Building C object CMakeFiles/nev.dir/back/bytecode.c.o
[  7%] Building C object CMakeFiles/nev.dir/back/dlcache.c.o
In file included from /home/nchatterjee/projects/clonedlanguages/never/back/dlcache.c:2:
/home/nchatterjee/projects/clonedlanguages/never/back/fficall.h:27:10: fatal error: ffi.h: No such file or directory
 #include <ffi.h>
          ^~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/nev.dir/build.make:124: CMakeFiles/nev.dir/back/dlcache.c.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/nev.dir/all] Error 2
make: *** [Makefile:95: all] Error 2

How do I fix this?

Documentation of c-api functions

I would love to know what each of the functions returns and perhaps a little bit of what each function does. Like while looking through object.h:134 I see that it returns char is that because you don't want to use bool for some reason? I am working on a library for rust to allow this to be embedded into a rust program and would love some more documentation.

Integer rollover (would affect float as well)

I was playing around doing some bench marking between python and never and quickly rolled over int.

I see that no native int/float other than the standard 32 bit int and float are supported...
https://github.com/never-lang/never/blob/master/back/gc.c

Would be nice to support 64 and 128 bit int (latter is supported on 64 bit hardware as __int128)
(As well as double and long double)

But never is nice and simple and clean as is.... But lack of 64 bit integers is going to limit my use of never....

I'd might be able to do the grunt work if the PRs would be accepted, as I'd rather not maintain my own version of never.

REPL and incremental compilation

Off hand I don't see any way to incrementally compile code then parts of it...
I seem to only be able to compile whole programs (I'm working on a CLI REPL by embedding never in a C program).

Has there been any thought put into how a REPL could work in never?
I'll do some digging through and see what I can figure out.

If I can't do it from the outside (embedding never, setting up various data structures, and calling various functions in the nev library) I'll consider branching and making it work then doing a PR. But until we have a discussion I rather not go down the path of modifying the never code to support this.

Segmentation Fault

I get Segmentation fault: 11 on OSX for following example:

func main() -> float
{
    func fib(float n) -> float
    {
        return (n == 0) ? 1 : (n == 1) ? 1 : fib(n - 1) + fib(n - 2);
    }
    return fib(7);
}

Nice language, VM could be sped up significantly most likely

Very nice language, and from I can tell from just a short time of playing around with it, it is very fast.
Good work!

However, the never-lang VM looks looks to be using indirect call threading.

https://github.com/never-lang/never/blob/master/back/vmexec.c#L3185

Unless I'm wrong (only studied the code less than an hour) the VM could be sped up significantly, but it would take some rework.

https://eli.thegreenplace.net/2012/07/12/computed-goto-for-efficient-dispatch-tables
https://en.wikipedia.org/wiki/Threaded_code#Indirect_threading
https://www.complang.tuwien.ac.at/forth/threaded-code.html <-- See bottom of that page for the method never-lang appears to be using.

Many other interpreted languages have gone through this as they matured....
If I find some time, I'll look at cloning never-lang/never, reworking the VM, doing a set of benchmarks on the existing vs a reworked implementation, and would do a PR. No promises though. I'd also hold off on starting any of that until after a discussion here.

Once again, good work! This is merely an observation of something that could be improved with never-lang.

question about FFI

Hello,
The FFI works great in the Never language, at least for int's, float's and const strings. However...

I have the following C-code:

char *get(char *s) { return s; }
char *conc(char *s1,char *s2) {
static char buf[20];
sprintf(buf,"%s%s",s1,s2);
return buf;
}

I try it in Never as follows:

extern "./issue.so" func get(s:string) -> string
extern "./issue.so" func conc(s1: string, s2:string) -> string
func main() -> int {
prints(get("come on\n"));
prints(conc("come ","on\n")); /* <-- crash */
0
}

It appears that the first statement is okay, but the second ends in a crash. Is there anything that can be done to make this work?

Best regards,
Wouter Boeke

Added Never to Rosetta Code

Hello Slawomir,

Just added Never to Rosetta Code, https://rosettacode.org/wiki/Category:Never

Being totally new to Never, I may not have all the details technically correct, so would appreciate your opinions and preferences on how to expand of the language page summary.

And, is there a way to not display the result of main, other than redirecting stderr to the null device? A lot of the basic Rosetta tasks are console IO based, and running with 2>/dev/null for captures seems less than optimal in terms of introductory demonstrations. Especially for things like Hello, world.

Have good, make well,
Brian

Documention for embedding has not been updated in a while

See https://never-lang.readthedocs.io/en/latest/#c-language

  1. nev_execute now takes a vm argument. No problem, I used vm_new to create one and then provide it.
  2. prog->params was not initialized.

I used the the following to initialize machine and prog->params.

    program * prog = program_new(); 
    vm* machine = vm_new(mem_size, stack_size);
    object* p1 = object_new_int(0);
    object* p2 = object_new_int(0);
    object params[] = {*p1, *p2};
    prog->params = params;

However, when I went to execute that I got:

unhandled nil_pointer exception
machine:
	sp: 26
	fp: 25
	gp: 0
	ip: 96
	except: 8
	line_no: 1
	stack_size: 16384
	mem_size: 16384
	running: 3
	message: VM_ERROR

called from line 1 ip:92 fp:25
unhandled nil_pointer exception
machine:
	sp: 32
	fp: 31
	gp: 0
	ip: 96
	except: 8
	line_no: 1
	stack_size: 16384
	mem_size: 16384
	running: 3
	message: VM_ERROR

called from line 1 ip:92 fp:31
called from line 1 ip:92 fp:25

Command-line arguments

How does a program get its command-line arguments? I can't seem to find anything in the documentation. The closest thing I found is this. However, there doesn't seem to be anything called nev that I can use.

Why does putting something in module affect tail calls?

If I do this:

use libc
func octal (x:string) -> int { libc.strtol(x, c_null, 8) }
func spaces(n: int) -> string {
    func spaces0(s:string, n:int) -> string {
        (n == 0) ? s : spaces0(s+" ", n-1)
    }
    spaces0(" ", n-1)
}

It works fine.
But if I put it in a module:

module strutil {
    use libc
    func octal (x:string) -> int { libc.strtol(x, c_null, 8) }
    func spaces(n: int) -> string {
        func spaces0(s:string, n:int) -> string {
            (n == 0) ? s : spaces0(s+" ", n-1)
        }
        spaces0(" ", n-1)
    }
}

I get this when spaces is called:

stack too large
machine:
	sp: 200
	fp: 199
	gp: 167
	ip: 602
	except: 0
	line_no: 7
	stack_size: 200
	mem_size: 5000
	running: 1
	message: stack too large

For both cases I'm calling spaces(1001) and it is fine for the non module use case.

If I change spaces to use a loop rather than tail calls, then it works.

    func spaces(n: int) -> string {
        var s = "";
        while (n > 0) {
            s = s + " ";
            n = n - 1
        };
        s
    }    

test/test_inttab.c: constant comparison

In lines 62-66:

for (value = 16; value < 16; value++)
    {
        inttab_entry * entry = inttab_lookup(tab, value);
        assert(entry != NULL && entry->value == value);
    }

and lines 81-85:

for (value = 16; value < 16; value++)
    {
        inttab_entry * entry = inttab_lookup(tab, value);
        assert(entry != NULL && entry->value == value);
    }

value is always >= 16 and these statements will always evaluate to false. Comparison is redundant and suggests the possibility of a bug.

Grammar railroad diagram

Hello !

I've done some work to convert bison grammars to EBNF understood by https://www.bottlecaps.de/rr/ui and applying it to this project parser.y and with a bit of manual fixes I've got the EBNF shown bellow, copy and paste it on the tab Edit Grammar at https://www.bottlecaps.de/rr/ui then switch to the tab View Diagram.

I hope it'll help potential users to understand never language !

Cheers !

start::= never
start::= module_decl
module_decl::= TOK_MODULE TOK_ID '{' never '}'
module_decl::= TOK_MODULE_REF
never::= use_list decl_list
never::= decl_list
never::= use_list decl_list seq_list
never::= use_list seq_list
never::= decl_list seq_list
never::= seq_list
use_list::= use_list use
use_list::= use
use::= TOK_USE TOK_NUM_STRING module_decl
decl_list::= decl_list decl
decl_list::= decl
decl::= record
decl::= enumtype
record::= TOK_RECORD TOK_ID '{' param_seq '}'
enumtype::= TOK_ENUM TOK_ID '{' enum_list '}'
enum_list::= enum_list ',' enum_item
enum_list::= enum_item
enum_item::= TOK_ID '=' expr
enum_item::= TOK_ID
enum_item::= TOK_ID '{' param_seq '}'
func::= TOK_FUNC TOK_ID error
func::= TOK_EXTERN TOK_NUM_STRING TOK_FUNC func_decl
func::= TOK_FUNC func_decl func_body func_except
func::= TOK_FUNC func_decl func_body
func_except::= except_list except_all
func_except::= except_list
func_except::= except_all
except_list::= except_list except
except_list::= except
except::= TOK_CATCH '(' TOK_ID ')' seq
except_all::= TOK_CATCH seq
func_body::= '{' '}'
func_body::= seq
func_decl::= TOK_ID '(' param_list ')' TOK_RET param
func_decl::= TOK_ID '(' ')' TOK_RET param
func_decl::= '(' param_list ')' TOK_RET param
func_decl::= '(' ')' TOK_RET param
param_seq::= param_seq param ';'
param_seq::= param ';'
param_list::= param_list ',' param
param_list::= param
param::= TOK_VAR param_decl
param::= TOK_LET param_decl
param::= param_decl
param_decl::= TOK_ID ':' '(' param_list ')'
param_decl::= '(' param_list ')'
param_decl::= TOK_ID '(' param_list ')' TOK_RET param
param_decl::= TOK_ID '(' ')' TOK_RET param
param_decl::= '(' param_list ')' TOK_RET param
param_decl::= '(' ')' TOK_RET param
param_decl::= TOK_ID '[' range_dim_list ']' ':' param
param_decl::= '[' range_dim_list ']' ':' param
param_decl::= TOK_ID '[' range_dim_list ']' ':' TOK_RANGE
param_decl::= '[' range_dim_list ']' ':' TOK_RANGE
param_decl::= TOK_ID '[' dim_list ']' ':' param
param_decl::= '[' dim_list ']' ':' param
param_decl::= TOK_ID ':' TOK_ID TOK_DOT TOK_ID //%prec TOK_RET
param_decl::= TOK_ID ':' TOK_ID //%prec TOK_RET
param_decl::= TOK_ID TOK_DOT TOK_ID //%prec TOK_RET
param_decl::= TOK_ID //%prec TOK_RET
param_decl::= TOK_ID ':' TOK_C_PTR
param_decl::= TOK_C_PTR
param_decl::= TOK_VOID
param_decl::= TOK_ID ':' TOK_STRING
param_decl::= TOK_STRING
param_decl::= TOK_ID ':' TOK_CHAR
param_decl::= TOK_CHAR
param_decl::= TOK_ID ':' TOK_DOUBLE
param_decl::= TOK_DOUBLE
param_decl::= TOK_ID ':' TOK_FLOAT
param_decl::= TOK_FLOAT
param_decl::= TOK_ID ':' TOK_LONG
param_decl::= TOK_LONG
param_decl::= TOK_ID ':' TOK_INT
param_decl::= TOK_INT
param_decl::= TOK_ID ':' TOK_BOOL
param_decl::= TOK_BOOL
range_dim_list::= range_dim_list ',' range_dim
range_dim_list::= range_dim
range_dim::= TOK_ID TOK_TODOTS TOK_ID
range_dim::= TOK_TODOTS
dim_list::= dim_list ',' dim
dim_list::= dim
dim::= TOK_ID
expr::= '[' expr_range_dim_list ']'
expr_range_dim_list::= expr_range_dim_list ',' expr_range_dim
expr_range_dim_list::= expr_range_dim
expr_range_dim::= expr TOK_TODOTS expr
seq::= '{' seq_list '}'
seq_list::= seq_list ';' expr
seq_list::= seq_list ';' func
seq_list::= seq_list func
seq_list::= seq_list ';' var
seq_list::= seq_list ';' let
seq_list::= expr
seq_list::= func
seq_list::= var
seq_list::= let
var::= TOK_VAR TOK_ID '=' expr
let::= TOK_LET TOK_ID '=' expr
expr_list::= expr_list ',' expr
expr_list::= expr
expr::= touple
touple::= '(' expr ',' expr_list ')' ':' '(' param_list ')'
touple::= '(' expr ',' ')' ':' '(' param_list ')'
expr::= expr TOK_DOT TOK_ID
expr::= TOK_MATCH expr '{' match_guard_list '}'
expr::= TOK_MATCH expr '{' '}'
match_guard_list::= match_guard_list match_guard ';'
match_guard_list::= match_guard ';'
match_guard::= TOK_ELSE TOK_RET expr
match_guard::= match_guard_record TOK_RET expr
match_guard::= match_guard_item TOK_RET expr
match_guard_record::= TOK_ID TOK_DOT TOK_ID TOK_DDOT TOK_ID '(' matchbind_list ')'
match_guard_record::= TOK_ID TOK_DDOT TOK_ID '(' matchbind_list ')'
match_guard_item::= TOK_ID TOK_DOT TOK_ID TOK_DDOT TOK_ID
match_guard_item::= TOK_ID TOK_DDOT TOK_ID
matchbind_list::= matchbind_list ',' matchbind
matchbind_list::= matchbind
matchbind::= TOK_ID
expr::= iflet
iflet::= TOK_IF TOK_LET '(' match_guard_record '=' expr ')' expr TOK_ELSE expr //%prec TOK_ELSE
iflet::= TOK_IF TOK_LET '(' match_guard_item '=' expr ')' expr TOK_ELSE expr //%prec TOK_ELSE
iflet::= TOK_IF TOK_LET '(' match_guard_record '=' expr ')' expr //%prec TOK_IF
iflet::= TOK_IF TOK_LET '(' match_guard_item '=' expr ')' expr //%prec TOK_IF
expr::= TOK_FOR '(' TOK_ID TOK_IN expr ')' expr //%prec TOK_FOR
expr::= TOK_FOR '(' expr ';' expr ';' expr ')' expr //%prec TOK_FOR
expr::= TOK_DO expr TOK_WHILE '(' expr ')'
expr::= TOK_WHILE '(' expr ')' expr
expr::= seq
expr::= expr '=' expr
expr::= expr '(' expr_list ')'
expr::= expr '(' ')'
expr::= TOK_LET func
listcomp::= '[' expr '|' qualifier_list ']' ':' param
qualifier_list::= qualifier_list ';' qualifier
qualifier_list::= qualifier
qualifier::= generator
generator::= expr //* filter //*/
generator::= TOK_ID TOK_IN expr
expr::= listcomp
array_sub_list::= array_sub_list ',' array_sub
array_sub_list::= array_sub
array_sub::= '[' array_sub_list ']'
array_sub::= '[' expr_list ']'
array::= '[' array_sub_list ']' ':' param
array::= '[' expr_list ']' ':' param
array::= ARR_DIM_BEG expr_list ARR_DIM_END ':' param
expr::= expr '[' expr_range_dim_list ']'
//* array or slice or range slice //*/
expr::= expr '[' expr_list ']'
//* array dereference //*/
expr::= array
expr::= TOK_IF '(' expr ')' expr TOK_ELSE expr //%prec TOK_ELSE
expr::= TOK_IF '(' expr ')' expr //%prec TOK_IF
expr::= expr '?' expr ':' expr
expr::= '(' expr ')'
expr::= expr TOK_BIN_SHR expr
expr::= expr TOK_BIN_SHL expr
expr::= expr TOK_BIN_XOR expr
expr::= expr TOK_BIN_OR expr
expr::= expr TOK_BIN_AND expr
expr::= TOK_BIN_NOT expr
expr::= TOK_NOT expr
expr::= expr TOK_PIPEL expr
expr::= expr TOK_OR expr
expr::= expr TOK_AND expr
expr::= expr TOK_NEQ expr
expr::= expr TOK_EQ expr
expr::= expr TOK_GTE expr
expr::= expr '>' expr
expr::= expr TOK_LTE expr
expr::= expr '<' expr
expr::= expr '%' expr
expr::= expr '/' expr
expr::= expr '*' expr
expr::= expr '-' expr
expr::= expr '+' expr
expr::= '-' expr //%prec TOK_NOT
expr::= TOK_C_NULL
expr::= TOK_NIL
expr::= expr TOK_DDOT TOK_ID
expr::= TOK_NUM_STRING
expr::= TOK_NUM_CHAR
expr::= TOK_NUM_DOUBLE
expr::= TOK_NUM_FLOAT
expr::= TOK_NUM_LONG
expr::= TOK_NUM_INT
expr::= TOK_ID
expr::= TOK_FALSE
expr::= TOK_TRUE

TOK_BOOL ::= "bool"
TOK_TRUE ::= "true"
TOK_FALSE ::= "false"
TOK_CATCH ::= "catch"
TOK_CONST ::= "const"
TOK_FOR ::= "for"
TOK_LET ::= "let"
TOK_VAR ::= "var"
TOK_FUNC ::= "func"
TOK_WHILE ::= "while"
TOK_DO ::= "do"
TOK_IF ::= "if"
TOK_IN ::= "in"
TOK_ENUM ::= "enum"
TOK_ELSE ::= "else"
TOK_EXTERN ::= "extern"
TOK_INT ::= "int"
TOK_FLOAT ::= "float"
TOK_CHAR ::= "char"
TOK_STRING ::= "string"
TOK_C_PTR ::= "c_ptr"
TOK_C_NULL ::= "c_null"
TOK_VOID ::= "void"
TOK_NIL ::= "nil"
TOK_MATCH ::= "match"
TOK_RANGE ::= "range"
TOK_MODULE ::= "module"
TOK_USE ::= "use"
TOK_LONG ::= "long"
TOK_DOUBLE ::= "double"
TOK_BIN_NOT ::= "~~~"
TOK_BIN_AND ::= "&&&"
TOK_BIN_OR ::= "|||"
TOK_BIN_XOR ::= "^^^"
TOK_BIN_SHL ::= "<<<"
TOK_BIN_SHR ::= ">>>"
TOK_DDOT ::= "::"
TOK_TODOTS ::= ".."
TOK_EQ ::= "=="
TOK_NEQ ::= "!="
TOK_LTE ::= "<="
TOK_GTE ::= ">="
TOK_RET ::= "->"
TOK_IN ::= "<-"
TOK_AND ::= "&&"
TOK_OR ::= "||"
TOK_NOT ::= "!"
ARR_DIM_BEG ::= "{["
ARR_DIM_END ::= "]}"
TOK_DOT ::= "."
TOK_PIPEL ::= "|>"

Any plans for GC?

Do you plan on implementing garbage collection? I've seen other issues in your log where individuals consider Never to not be a functional language because of mutability. That would eliminate Clojure as function given it's mutable underpinnings.

However; scalar or data types (lists, maps, sets, etc.) could all be immutable but the issue is it tends to generate a significant ancestry especially with heavy iteration, reductions, etc.

Exits from the VM (And error checking an error handling in general)

(For errors that are not caught by the VM runtime)

This issue is mainly to track future improvements to Never.

Not really a priority now, but there should be a better mechanism for trapping some things than exiting the whole program.

I understand that divide by zero is different from illegal opcode.
Divide by zero is caught by the runtime, but illegal opcode currently just causes an exit (as does stack overflow). (I've not ran into that yet, I'm just pointing it out as an example). As far as stack overflow, guard pages could be used along with signal handlers. This would allow the VM to run faster without as many checks. Might be able to do the same for divide by zero.

Long term there should maybe be a way to return back to the hosting app, and let it decide what to do with that, rather then terminate the entire program.

Maybe using setjmp/longjmp, to exit the VM back to the API function called by the hosting program, so that a proper error can be returned.

Will there any support of generic types?

Hi, this is a quite interesting language but as I understand I should always specify a concrete type in structs and functions. Do you have any plans for generic functions and structs?

Any way to create a set of constants?

Never's enums are not like C's enums, so they can't be used in this way... (As far as I can tell).
Right now the only way I see to do that is create functions that return the desired values.

func O_RDONLY() -> int { 0 }
func O_WRONLY() -> int { 1 }
func O_RDWR() -> int { 2 }

extern "libc.so.6" func strlen(x : string) -> int
extern "libc.so.6" func strtol(x : string, end: c_ptr, base:int) -> int
extern "libc.so.6" func open(path:string, flags:int, mode:int) -> int 
extern "libc.so.6" func creat(path:string, mode:int) -> int 
extern "libc.so.6" func unlink(path:string) -> int 
extern "libc.so.6" func read(fd:int, buf:string, count:int) -> int
extern "libc.so.6" func write(fd:int, buf:string, count:int) -> int
extern "libc.so.6" func close(fd:int) -> int

func octal (x:string) -> int { strtol(x, c_null, 8) }

func spaces(n: int) -> string {
    func spaces0(s:string, n:int) -> string {
        (n == 0) ? s : spaces0(s+" ", n-1)
    }
    spaces0(" ", n-1)
}

func write_file(path:string, test_txt:string) -> int {
    let mode = octal("644");
    let fd = creat(path, mode);
    let n = strlen(test_txt);
    assert (fd != 0);
    assert (n == write(fd, test_txt, n));
    assert (0 == close(fd));
    0
}

func read_file(path:string, maxbuf:int) -> string {
    let buffer = spaces(maxbuf+1);
    let fd = open(path, O_RDONLY(), 0);
    let n = read(fd, buffer, maxbuf);
    let result = buffer[0..n-1];
    assert (fd != 0);
    assert (0 < n);
    assert (0 == close(fd));
    result
}

func main() -> int {
    let test_txt = "sample text\n";
    let path = "test.txt";
    write_file(path, test_txt);
    prints(read_file("/proc/version", 1000));
    assert (read_file(path, 1000) == test_txt);
    0
}

Also, and these are separate issues, is there any way to reserve space for a string?
The way I'm doing it with func spaces(n: int) -> string is a bit crude...
Also, using func strlen(x : string) -> int from libc.so.6 to get string length is a bit crude.

Also not being able to mix let statements with other code is a bit awkward. But yeah, never is intended to a a functional language, not an imperative one...
I guess one could create the variables with var, then assign them later so variable declarations and code could be mixed, but that sacrifices immutability.

Hex, octal, binary literals would be nice for integers (and a way of specifying size) so one does not need to use strtol(x : string, end: c_ptr, base:int) from libc.so.6. Not something you would need to do, if you were willing to have them added, that is another thing I'll look into doing.

Question: Official release

When is the next official release of the Never language? For my programming language docker images, I prefer to use a release tag. Currently, I'm just using the latest commit hash.

Some questions

  1. let vs var are these the same except for one being mutable?
  2. Type inference -- it looks like value bindings (let/var) can be inferred, but function signatures (even for small lambdas) have to be explicitly written. Is that correct?
  3. If I nev_compile_* two different things with the same program, what happens? Does the second just overwrite the first?
  4. Is there any facility to import one nev file from another, or is the idea that you're always embedding roughly self-contained scripts?

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.