Giter Club home page Giter Club logo

cont's Introduction

Cont

Static Badge

Cont is a compiled statically-typed concatenative programming language, that has elements of OOP, is written in Python and is inspired by Porth.

Where did the name come from

From word concatinative. How have I come up with that specific word? I just mixed beginning of that word and tried to come up with something, that sounds good.

Quick Start

$ python3 -V
 Python >=3.10

$ git clone https://github.com/farkon00/cont.git
$ cd cont

# Install fasm with your package manager, nodejs and wabt (https://github.com/WebAssembly/wabt) for testing wasm
$ sudo apt install fasm nodejs wabt
$ python3 -m pip install pytest
$ pytest test.py

$ python3 cont.py <source_code>.cn -r

Examples

You can find examples on how to use the language in the tests or examples folders or in the standard library source, which can be found in the std directory.

Please note that tests are contained in one file, so the only part of the test file, which contains cont code is the first one, before the first occurence of a line that contains a single colon symbol and nothing else.

cont's People

Contributors

datawater avatar ellipse0934 avatar farkon00 avatar

Stargazers

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

Watchers

 avatar  avatar  avatar

cont's Issues

Malloc size behaving incorrectly

The following code triggers a bug, that changes size of the second block to 33, while it's actually 22.

include std.cn

5 malloc
bind mem:
  "Hello" mem memcpy
  5 mem println
  6 mem extend_alloc
  print_malloc_list
  " world" mem 5 ptr+ memcpy 
  11 mem println
  1 mem extend_alloc
  '!' mem 11 ptr+ !8
  print_malloc_list
  12 mem println
end

Add sproc

There is some situations, where you want to bind a self, but not the rest of the arguments. And sproc gonna do that.

Example of __init__ for File in io.cn:

sproc __init__ int @str:
    str_to_nstr
    bind path:
      path open2
      dup self.check_fd
      !self.fd

      path free
    end
  end

Highest common ancestor for branch type checking

Right now type_checking.check_route_stack() can only cast to one of the types in the branches. So if we take wasm/web.cn as an example, if one branch results in a JSEvent and another one in JSObject the result would be a JSObject, but if one result in JSObject and another one results in JSNull it would cause a type checking error. A better behavior for the later situation would be to result in a common ancestor of JSObject and JSNull, which is JSValue.

Example of code:

sproc is_equal_node JSNode -> int:
    if dup NULL ptr== do
      drop 
      init var null JSNull null
    end
    ...
end

The if block should result in JSValue.

So whats next?

So I kinda run out of ideas. Leave a comment for this issue, if you have any. But please check if idea was already implemented in commits or in examples.

Procedure type checking is broken

Because of the recent change to branch type checking the following code compiles, but it obviously shouldn't.

include std.cn

struct A
  int a
end

struct (A) B
  int b
end

struct (A) C
  int c
end

proc a int int -> C:
  B
end

[BUG] State.locs_to_include out of bounds

Compiling the following code

const SYSEXIT 60 end

proc exit int: SYSEXIT syscall1 drop end 

1 exit

will lend in the following error message

Traceback (most recent call last):
  File "/home/datawater/Desktop/Programming/third-party/cont/playground/../cont", line 99, in <module>
    main()
  File "/home/datawater/Desktop/Programming/third-party/cont/playground/../cont", line 94, in main
    compile_ops(ops)
  File "/home/datawater/Desktop/Programming/third-party/cont/generating/generating.py", line 16, in compile_ops
    return TARGETS[State.config.target](ops)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/datawater/Desktop/Programming/third-party/cont/generating/fasm_x86_64_linux.py", line 36, in compile_ops_fasm_x86_64_linux
    f.write(generate_fasm_x86_64_linux(ops))
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/datawater/Desktop/Programming/third-party/cont/generating/fasm_x86_64_linux.py", line 130, in generate_fasm_x86_64_linux
    buf += generate_op_fasm_x86_64_linux(op)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/datawater/Desktop/Programming/third-party/cont/generating/fasm_x86_64_linux.py", line 328, in generate_op_fasm_x86_64_linux
    return comment + generate_operator_fasm_x86_64_linux(op)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/datawater/Desktop/Programming/third-party/cont/generating/fasm_x86_64_linux.py", line 636, in generate_operator_fasm_x86_64_linux
    f"mov r12, {len(State.locs_to_include[op.loc_id]) + 1}\n"
                    ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
IndexError: list index out of range

Command used to compile python3 cont minimal.cn

Uname: Linux farkonisaboykisser 6.6.6-200.fc39.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Dec 11 17:29:08 UTC 2023 x86_64 GNU/Linux

Complicated control flow: return, break, continue

This feature would require adding 3 keywords: return, break and continue. The first one returns from a procedure and should check if the return types match. The break stops the loop and jumps to the end of it and continue stops the current iteration and jumps to the condition checking. The latter two should check, that the types match those at the regular end of the loop and those, that are on the stack before before the loop starts.

It is important, that those keywords impact branch type checking, so if you are guaranteed to return in a branch there should be no type checking at the end. For example the following code should compile even though the type checking without the return would fail.

nproc dealloc ptr p:
  if p NULL ptr== do
    return p p
  end
  p free
end

Binding shadowing not working correctly

Bindings do not shadow and nor do they throw a compiler error. Expected behavior for the following piece of code would be to print 4\n1\n and not 1\n1\n, as it is right now.

1
bind a:
  a 3 +
  bind a:
    a print
  end
  a print
end

Make generating.py look nicer

We should change the way we do big assembly from this

return (
    comment
    + """
pop rax
pop rbx
add rax, rbx
push rax
"""

to this

return comment + (
    "pop rax\n"
    "pop rbx\n"
    "add rax, rbx\n"
    "push rax\n"
)

Note that there are no commas between strings

Bug in parsing of unpacking

If a type is being parsed in a context, that allows unpacking the compiler allows unpacking inside pointers, which should be impossible. And might result in a compiler crush.

NOTE: the bug is clearly located in types.parse_type()

include std.cn

struct Cursed
  int x
  int y
end

proc test *@Cursed:
  print
end
Error baz:9:7: unexpected argument type
Traceback (most recent call last):
  File "/home/farkon/data/cont/cont.py", line 97, in <module>
    main()
  File "/home/farkon/data/cont/cont.py", line 78, in main
    type_check(ops, is_main=True)
  File "/home/farkon/data/cont/type_checking/type_checking.py", line 83, in type_check
    new_op = type_check_op(op, stack)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/farkon/data/cont/type_checking/type_checking.py", line 380, in type_check_op
    process_call(op, stack)
  File "/home/farkon/data/cont/type_checking/type_checking.py", line 194, in process_call
    check_stack(stack, in_types)
  File "/home/farkon/data/cont/type_checking/type_checking.py", line 21, in check_stack
    f"\033[1;34mArgument {i+1+arg}\033[0m: {type_to_str(got)} instead of {type_to_str(exp)}\n"
                                            ^^^^^^^^^^^^^^^^
  File "/home/farkon/data/cont/type_checking/types.py", line 195, in type_to_str
    return "*" + type_to_str(_type.typ)
                 ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/farkon/data/cont/type_checking/types.py", line 207, in type_to_str
    cont_assert(False, f"Unimplemented type in type_to_str: {_type}")
  File "/home/farkon/data/cont/state.py", line 17, in cont_assert
    raise InternalAssertionError(message)
state.InternalAssertionError: Unimplemented type in type_to_str: [<type_checking.types.Int object at 0x7fef90e59610>, <type_checking.types.Int object at 0x7fef90e596d0>]

Add to README.md

It would be interesting to put in README.md, installing fasm and pytest. Which are essential to run the cont.

Improving error handling

Make assert throw a cont error using some meta programming and by wrapping all the code into try: except AssertionError: <Error handling>. Replace actual asserts with some exception.

Also that would be a great idea to clean up all of the insane State.loc stuff.

Update README.md to inform about the wabt dependencie

The README lists fasm nodejs and pytest as the only build/test dependencies, even though wabt is also required. Running tests without wabt installed will throw the following error

E       AssertionError: assert 'Please insta...ecifically.\n' == '69\n42\n69\n...7)\n1\n0\n1\n'
E         + Please install wabt and wat2wasm specifically.
E         - 69
E         - 42
E         - 69
E         - 42
E         - 0
E         - 3...
E
E         ...Full output truncated (13 lines hidden), use '-vv' to show

Documentation discussion

This is a thread for tracking the progress and communicating ideas on adding more documentation to the project and presenting it to the users in a better way.

The main maintainer for this thread is @Ellipse0934, but feel free to join in and help with the discussion or the actual documentation, if you have any questions regarding the latter you can ask questions here.

The pinned concern and working area, we are focusing on right now, is the "Learn Cont" manual.

Interface for types

Add an interface for different types representing cont types in a compiler.

Make UPCAST use malloc for fasm x86_64 linux

UPCAST right now can only use two brk syscalls for allocating memory, it should behave more like PACK operations, which can use both malloc and two syscalls for allocating memory.

Add a Dockerfile

Having a dockerfile is a convenient way for devs to bootstrap quickly irrespective of OS/package manager. Will allow them to dip their toes in the project without having to install and manage deps.

I personally don't have apt or python installed and it creates an overhead for me to install and later remember to gc it. We could add a dockerfile in the project to be a little helpful.

FROM debian

SHELL ["/bin/bash", "-c"]

RUN apt-get update
RUN apt install -y git \
    python3 \
    python3-pytest \
    fasm \
    nodejs \
    wabt 

RUN groupadd -g 2000 bischebis \
&& useradd -m -u 2001 -g bischebis bischebis

USER bischebis
WORKDIR /home/bischebis
RUN git clone https://github.com/farkon00/cont
WORKDIR cont

and run via
docker run -it cont:latest

May I add ? uwu

Add typed addrs

Right now addreses(function pointers) have only one type for them addr. Which is not that safe. The better way is to type procedures by their arguments and return types. I don't think, that inlining a signature would be a great idea, because it will be too big and hard to parse. The better approach is to just use already existing procedures as signatures, we are already using this approach, when doing call_like. Tho creating a new keyword predicate would be the best option, but it may take more effort. The two possible implementations look like this.

include std.cn

proc IterPredicate int:
  drop
end

proc iter IterPredicate ptr:
  ...
end

*print NULL iter

or

include std.cn

predicate IterPredicate int;

proc iter IterPredicate ptr:
  ...
end

*print NULL iter

Also in case we are going to use the first way we might use addr or like before the procedure name.

Add the warning if fasm was not found

How about checking if fasm is installed when the cont starts and throw an error with an instrctruction to install it using apt if it was not found.

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.