Coder Social home page Coder Social logo

concoctist / concoct Goto Github PK

View Code? Open in Web Editor NEW
11.0 11.0 1.0 472 KB

🧪 An imperative, dynamically-typed, interpreted, general-purpose programming language

Home Page: http://concoct.ist/

License: BSD 2-Clause "Simplified" License

CMake 1.28% C 98.55% Dockerfile 0.17%
c cmake cross-platform dynamically-typed general-purpose imperative interpreter lexer multiplatform object-oriented-programming parser portable procedural-programming programming-language register-machine scripting-language stack-based strongly-typed tokenizer virtual-machine

concoct's People

Contributors

bamalot avatar dependabot[bot] avatar ldilley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

ldilley

concoct's Issues

Add various runtime options

Accept at least the runtime options below. Prefix the option with / on Windows and use - on other platforms.

  • c: Store compaction factor (defaults to 25%)
  • d: Debug mode
  • e: Store expansion factor (defaults to 50%)
  • g: Store growth threshold (defaults to 10%)
  • h: Display help
  • i: Initial store size (defaults to 128)
  • l: Display license
  • m: Max stack size (defaults to 64)
  • r: Use registers instead of the stack for most operations
  • s: Store shrink threshold (defaults to 75% and new size never falls below INITIAL_STORE_SIZE)
  • v: Display version

Enable interactive mode

If concoct is executed with no arguments, it should start in interactive mode similar to Python. Users can evaluate expressions and run statements within the interactive prompt if desired.

Add microseconds to debug timestamp

Feature Description

  • Add microseconds to debug timestamp to show greater precision for elapsed time between operations. This feature should be portable.

Handle EOT in REPL

Feature Description

  • Handle end of transmission (EOT) input within the REPL (ctrl+d for Unix and ctrl+z for Windows).

Implement garbage collection

Implement a mark-and-sweep garbage collector. Each object now contains a marked boolean field for this purpose. Collection can occur whenever a new object is created.

Product of string multiplication includes garbage

Expected Behavior

  • foo = "bar" * 3 should result in "barbarbar".

Actual Behavior/Symptoms

  • If the first operation is string multiplication, the result is prefixed with garbage values. The result of subsequent operations does not contain the garbage values.

How to Reproduce Behavior/Symptoms

  • Run concoct and input foo = "bar" * 3 (or any arbitrary variable, string, and factor). Reversing the factors produces the same symptom (foo = 3 * "bar").

Concoct Version

  • 0.1.0

Compiler Version

  • Any

Operating System

  • Any

Output/Screenshot(s)

> foo = "bar" * 3
[1] foo : Identifier
[1]  : =
[1] bar : String
[1]  : *
[1] 3 : Int
New line ()
  = ()
    Identifier (foo)
    * ()
      String (bar)
      Int (3)
Debug: [08/08/2023 19:48:59 EDT (1691538539.211184) +/-5.113245] - Queue initialized with 256 slots.
Debug: [08/08/2023 19:48:59 EDT (1691538539.211225) +/-0.000041] - Memory allocated for string with length of 3 characters: bar
Debug: [08/08/2023 19:48:59 EDT (1691538539.211233) +/-0.000008] - Object of type string created with value: bar
Debug: [08/08/2023 19:48:59 EDT (1691538539.211253) +/-0.000020] - push() called on stack for object of type string. Stack now contains 1 objects.
Debug: [08/08/2023 19:48:59 EDT (1691538539.211263) +/-0.000010] - Object of type number created with value: 3
Debug: [08/08/2023 19:48:59 EDT (1691538539.211267) +/-0.000004] - Object of type number added to object store at slot 0.
Debug: [08/08/2023 19:48:59 EDT (1691538539.211272) +/-0.000005] - push() called on stack for object of type number. Stack now contains 2 objects.
Instruction: OP_MUL (0x21)
Debug: [08/08/2023 19:48:59 EDT (1691538539.211279) +/-0.000007] - pop() called on stack for object of type number. Stack now contains 1 objects.
Debug: [08/08/2023 19:48:59 EDT (1691538539.211282) +/-0.000003] - pop() called on stack for object of type string. Stack now contains 0 objects.
Debug: [08/08/2023 19:48:59 EDT (1691538539.211287) +/-0.000005] - Memory allocated for string with length of 15 characters: ���)barbarbar
Debug: [08/08/2023 19:48:59 EDT (1691538539.211306) +/-0.000019] - Object of type string created with value: ���)barbarbar
Debug: [08/08/2023 19:48:59 EDT (1691538539.211313) +/-0.000007] - Object of type string added to object store at slot 1.
Debug: [08/08/2023 19:48:59 EDT (1691538539.211334) +/-0.000021] - push() called on stack for object of type string. Stack now contains 1 objects.
Debug: [08/08/2023 19:48:59 EDT (1691538539.211358) +/-0.000024] - peek() called on stack for object of type string. Stack currently contains 1 objects.
���)barbarbar
Register values:
R0: empty
R1: empty
R2: empty
R3: empty
R4: empty
R5: empty
R6: empty
R7: empty
R8: empty
R9: empty
R10: empty
R11: empty
R12: empty
R13: empty
R14: empty
R15: empty
RS: empty
IP: OP_END (0x0B)
RP: 0x0
SP: ���)barbarbar (string)
Freed parser
Freed node tree
> foo = "bar" * 3
[1] foo : Identifier
[1]  : =
[1] bar : String
[1]  : *
[1] 3 : Int
New line ()
  = ()
    Identifier (foo)
    * ()
      String (bar)
      Int (3)
Debug: [08/08/2023 19:52:11 EDT (1691538731.373625) +/-192.162267] - Queue initialized with 256 slots.
Debug: [08/08/2023 19:52:11 EDT (1691538731.373667) +/-0.000042] - Memory allocated for string with length of 3 characters: bar
Debug: [08/08/2023 19:52:11 EDT (1691538731.373691) +/-0.000024] - Object of type string created with value: bar
Debug: [08/08/2023 19:52:11 EDT (1691538731.373699) +/-0.000008] - push() called on stack for object of type string. Stack now contains 2 objects.
Debug: [08/08/2023 19:52:11 EDT (1691538731.373704) +/-0.000005] - Object of type number created with value: 3
Debug: [08/08/2023 19:52:11 EDT (1691538731.373724) +/-0.000020] - Object of type number added to object store at slot 2.
Debug: [08/08/2023 19:52:11 EDT (1691538731.373752) +/-0.000028] - push() called on stack for object of type number. Stack now contains 3 objects.
Instruction: OP_MUL (0x21)
Debug: [08/08/2023 19:52:11 EDT (1691538731.373761) +/-0.000009] - pop() called on stack for object of type number. Stack now contains 2 objects.
Debug: [08/08/2023 19:52:11 EDT (1691538731.373782) +/-0.000021] - pop() called on stack for object of type string. Stack now contains 1 objects.
Debug: [08/08/2023 19:52:11 EDT (1691538731.373808) +/-0.000026] - Memory allocated for string with length of 9 characters: barbarbar
Debug: [08/08/2023 19:52:11 EDT (1691538731.373833) +/-0.000025] - Object of type string created with value: barbarbar
Debug: [08/08/2023 19:52:11 EDT (1691538731.373840) +/-0.000007] - Object of type string added to object store at slot 3.
Debug: [08/08/2023 19:52:11 EDT (1691538731.373842) +/-0.000002] - push() called on stack for object of type string. Stack now contains 2 objects.
Debug: [08/08/2023 19:52:11 EDT (1691538731.373863) +/-0.000021] - peek() called on stack for object of type string. Stack currently contains 2 objects.
barbarbar
Register values:
R0: empty
R1: empty
R2: empty
R3: empty
R4: empty
R5: empty
R6: empty
R7: empty
R8: empty
R9: empty
R10: empty
R11: empty
R12: empty
R13: empty
R14: empty
R15: empty
RS: empty
IP: OP_END (0x0B)
RP: 0x0
SP: barbarbar (string)

Freed parser
Freed node tree

Add debug mode

Add a runtime option (-d) to be more verbose when events such as memory allocations and frees occur.

Parser treats minus sign as subtraction in negative context

Expected Behavior

  • a = -3 + 3 should yield 0 (zero).

Actual Behavior/Symptoms

  • Operator - is always treated as a subtraction token (CCT_TOKEN_SUB). This can cause a stack underflow event and segmentation fault.

How to Reproduce Behavior/Symptoms

  • Run concoct and input: a = -3 + 3

Concoct Version

  • 0.1.0

Compiler Version

  • Any

Operating System

  • Any

Output/Screenshot(s)

> a = -3 + 3
[1] a : Identifier
[1]  : =
[1]  : -
[1] 3 : Int
[1]  : +
[1] 3 : Int
New line ()
  = ()
    Identifier (a)
    + ()
      - ()
        Int (3)
      Int (3)
Debug: [08/08/2023 20:20:00 EDT (1691540400.090409) +/-2.731624] - Queue initialized with 256 slots.
Debug: [08/08/2023 20:20:00 EDT (1691540400.090456) +/-0.000047] - Object of type number created with value: 3
Debug: [08/08/2023 20:20:00 EDT (1691540400.090471) +/-0.000015] - Object of type number added to object store at slot 0.
Debug: [08/08/2023 20:20:00 EDT (1691540400.090474) +/-0.000003] - push() called on stack for object of type number. Stack now contains 1 objects.
Debug: [08/08/2023 20:20:00 EDT (1691540400.090477) +/-0.000003] - Object of type number created with value: 3
Debug: [08/08/2023 20:20:00 EDT (1691540400.090480) +/-0.000003] - Object of type number added to object store at slot 1.
Debug: [08/08/2023 20:20:00 EDT (1691540400.090482) +/-0.000002] - push() called on stack for object of type number. Stack now contains 2 objects.
Instruction: OP_SUB (0x32)
Debug: [08/08/2023 20:20:00 EDT (1691540400.090489) +/-0.000007] - pop() called on stack for object of type number. Stack now contains 1 objects.
Debug: [08/08/2023 20:20:00 EDT (1691540400.090492) +/-0.000003] - pop() called on stack for object of type number. Stack now contains 0 objects.
Debug: [08/08/2023 20:20:00 EDT (1691540400.090505) +/-0.000013] - Object of type number created with value: 0
Debug: [08/08/2023 20:20:00 EDT (1691540400.090510) +/-0.000005] - Object of type number added to object store at slot 2.
Debug: [08/08/2023 20:20:00 EDT (1691540400.090513) +/-0.000003] - push() called on stack for object of type number. Stack now contains 1 objects.
Debug: [08/08/2023 20:20:00 EDT (1691540400.090519) +/-0.000006] - peek() called on stack for object of type number. Stack currently contains 1 objects.
0
Instruction: OP_ADD (0x00)
Debug: [08/08/2023 20:20:00 EDT (1691540400.090530) +/-0.000011] - pop() called on stack for object of type number. Stack now contains 0 objects.
Stack underflow occurred!
Operand 1 is NULL during ADD operation.
Debug: [08/08/2023 20:20:00 EDT (1691540400.090536) +/-0.000006] - peek() called on empty stack!
[1]    23491 segmentation fault

Implement stack-based VM

Define functions that initialize a VM, manage the stack via its pointers and peek/pop/push operations, handle frames/process instructions, and shut down the VM.

Allow multiplication of string objects

Feature Description

  • Support string multiplication in op_mul(). This would replicate Ruby's behavior of allowing operations like:
"foo" * 3 // = "foofoofoo"

String concatenation (+) is already supported.

OP_DIV and OP_SUB operand stack issue

Expected Behavior

  • a = 3 * 10 / 2 should yield 15.

Actual Behavior/Symptoms

  • a = 3 * 10 / 2 yields 0 (zero).

How to Reproduce Behavior/Symptoms

  • Input a = 3 * 10 / 2.

Concoct Version

  • 0.1.0

Compiler Version

  • Any

Operating System

  • Any

Output/Screenshot(s)

> a = 3 * 10 / 2
[1] a : Identifier
[1]  : =
[1] 3 : Int
[1]  : *
[1] 10 : Int
[1]  : /
[1] 2 : Int
New line ()
  = ()
    Identifier (a)
    / ()
      * ()
        Int (3)
        Int (10)
      Int (2)
Debug: [02/08/2023 22:34:06 EDT] - Queue initialized with 256 slots.
Debug: [02/08/2023 22:34:06 EDT] - Object of type number created with value: 2
Debug: [02/08/2023 22:34:06 EDT] - Object of type number added to object store at slot 5.
Debug: [02/08/2023 22:34:06 EDT] - push() called on stack for object of type number. Stack now contains 2 objects.
Debug: [02/08/2023 22:34:06 EDT] - Object of type number created with value: 3
Debug: [02/08/2023 22:34:06 EDT] - Object of type number added to object store at slot 6.
Debug: [02/08/2023 22:34:06 EDT] - push() called on stack for object of type number. Stack now contains 3 objects.
Debug: [02/08/2023 22:34:06 EDT] - Object of type number created with value: 10
Debug: [02/08/2023 22:34:06 EDT] - Object of type number added to object store at slot 7.
Debug: [02/08/2023 22:34:06 EDT] - push() called on stack for object of type number. Stack now contains 4 objects.
Instruction: OP_MUL (0x21)
Debug: [02/08/2023 22:34:06 EDT] - pop() called on stack for object of type number. Stack now contains 3 objects.
Debug: [02/08/2023 22:34:06 EDT] - pop() called on stack for object of type number. Stack now contains 2 objects.
Debug: [02/08/2023 22:34:06 EDT] - Object of type number created with value: 30
Debug: [02/08/2023 22:34:06 EDT] - Object of type number added to object store at slot 8.
Debug: [02/08/2023 22:34:06 EDT] - push() called on stack for object of type number. Stack now contains 3 objects.
Debug: [02/08/2023 22:34:06 EDT] - peek() called on stack for object of type number. Stack currently contains 3 objects.
30
Instruction: OP_DIV (0x0A)
Debug: [02/08/2023 22:34:06 EDT] - pop() called on stack for object of type number. Stack now contains 2 objects.
Debug: [02/08/2023 22:34:06 EDT] - pop() called on stack for object of type number. Stack now contains 1 objects.
Debug: [02/08/2023 22:34:06 EDT] - Object of type number created with value: 0
Debug: [02/08/2023 22:34:06 EDT] - Object of type number added to object store at slot 9.
Debug: [02/08/2023 22:34:06 EDT] - push() called on stack for object of type number. Stack now contains 2 objects.
Debug: [02/08/2023 22:34:06 EDT] - peek() called on stack for object of type number. Stack currently contains 2 objects.
0
Register values:
R0: empty
R1: empty
R2: empty
R3: empty
R4: empty
R5: empty
R6: empty
R7: empty
R8: empty
R9: empty
R10: empty
R11: empty
R12: empty
R13: empty
R14: empty
R15: empty
RS: empty
IP: OP_END (0x0B)
RP: 0x0
SP: 0 (number)

Update project license to 2-clause BSD License

Due to the LGPL being more restrictive in regards to static linking, @Bamalot and I have opted to use the more permissive 2-clause BSD License instead going forward. LICENSE.txt and the header of all source files should be updated to reflect this decision.

Allow object store to shrink

After adding a function to calculate occupied store slots, use the output to determine whether or not the object store should shrink. For example, if store consumption falls below 25%, trigger a shrink operation. The new size should never fall below INITIAL_STORE_CAPACITY.

Implement instructions

Add functions that perform various operations and correspond to Concoct's defined opcodes.

  • OP_ADD
  • OP_AND
  • OP_ASN
  • OP_BND
  • OP_BNT
  • OP_BOR
  • OP_CAL
  • OP_CLR
  • OP_CLS
  • OP_CMP
  • OP_DEC
  • OP_DIV
  • OP_END
  • OP_ENT
  • OP_EQL
  • OP_EXT
  • OP_FLS
  • OP_GT
  • OP_GTE
  • OP_HLT
  • OP_INC
  • OP_JMC
  • OP_JMP
  • OP_JMZ
  • OP_LNE
  • OP_LNZ
  • OP_LOD
  • OP_LOE
  • OP_LOP
  • OP_LOZ
  • OP_LT
  • OP_LTE
  • OP_MOD
  • OP_MOV
  • OP_MUL
  • OP_NEG
  • OP_NEQ
  • OP_NOP
  • OP_NOT
  • OP_NUL
  • OP_OR
  • OP_POP
  • OP_POS
  • OP_POW
  • OP_PSH
  • OP_RET
  • OP_SHL
  • OP_SHR
  • OP_SLE
  • OP_SLN
  • OP_STR
  • OP_SUB
  • OP_SYS
  • OP_TRU
  • OP_TST
  • OP_XCG
  • OP_XOR

Lexer improvement

  • Comment support
  • Optimized keyword recognition (most likely a hash map)
  • Support for lexing any string, not just a FILE pointer

Segfault occurs while parsing and lack of calls to free()

Expected Behavior

  • Concoct runs normally without error.

Actual Behavior/Symptoms

  • A segfault occurs near the end of parsing.

How to Reproduce Behavior/Symptoms

  • Using the latest commit at the time of this writing, 4d01b3d, attempt to parse parser_test.cct.

Concoct Version

Compiler Version

  • GCC 8.3.0

Operating System

  • Linux

Output/Screenshot(s)

Normal run output:

<18:23:51> (~/projects/concoct/bld)
[ldilley@genesis] :) {2985}$ bin/concoct ../src/tests/parser_test.cct
Concoct v0.1.0
Lexing ../src/tests/parser_test.cct:
[1] do : do
[1]  : {
[1]  : New line
[2] if : if
[2] Hello : String
[2]  : {
[2]  : New line
[3] for : for
[3] test : Identifier
[3] in : Token
[3] tests : Identifier
[3]  : {
[3]  : New line
[4] if : if
[4] test : Identifier
[4]  : {
[4]  : New line
[5] x : Identifier
[5]  : =
[5] 5 : Int
[5]  : New line
[6]  : }
[6]  : New line
[7]  : }
[7]  : New line
[8] msg : Identifier
[8]  : =
[8] Hello : String
[8]  : New line
[9]  : }
[9]  : New line
[10] y : Identifier
[10]  : =
[10] 3 : Int
[10]  : New line
[11]  : }
[11]  : New line
[12] while : while
[12] 5 : Int
New line ()
  do ()
    { ()
      if ()
        String (Hello)
        { ()
          for ()
            Identifier (test)
            Identifier (tests)
            { ()
              if ()
                Identifier (test)
                { ()
                  = ()
                    Identifier (x)
                    Int (5)
          = ()
            Identifier (msg)
            String (Hello)
      = ()
        Identifier (y)
        Int (3)
    Int (5)
Segmentation fault

Valgrind output:

==6581== Invalid read of size 8
==6581==    at 0x10B9AE: cct_delete_parser (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A426: parse_file (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A320: main (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==  Address 0x4a16340 is 0 bytes inside a block of size 32 free'd
==6581==    at 0x48369AB: free (vg_replace_malloc.c:530)
==6581==    by 0x10B9A9: cct_delete_parser (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A426: parse_file (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A320: main (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==  Block was alloc'd at
==6581==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==6581==    by 0x10B94C: cct_new_parser (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A3A7: parse_file (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A320: main (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==
==6581==
==6581== HEAP SUMMARY:
==6581==     in use at exit: 2,210 bytes in 48 blocks
==6581==   total heap usage: 66 allocs, 18 frees, 13,722 bytes allocated
==6581==
==6581== Searching for pointers to 48 not-freed blocks
==6581== Checked 67,464 bytes
==6581==
==6581== 1,072 (48 direct, 1,024 indirect) bytes in 1 blocks are definitely lost in loss record 45 of 46
==6581==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==6581==    by 0x10A74C: cct_new_file_lexer (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A499: lex_file (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A30D: main (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==
==6581== 1,138 (40 direct, 1,098 indirect) bytes in 1 blocks are definitely lost in loss record 46 of 46
==6581==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==6581==    by 0x10C310: cct_new_node (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10BAD4: cct_parse_program (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A3B7: parse_file (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A320: main (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==
==6581== LEAK SUMMARY:
==6581==    definitely lost: 88 bytes in 2 blocks
==6581==    indirectly lost: 2,122 bytes in 46 blocks
==6581==      possibly lost: 0 bytes in 0 blocks
==6581==    still reachable: 0 bytes in 0 blocks
==6581==         suppressed: 0 bytes in 0 blocks
==6581==
==6581== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
==6581==
==6581== 1 errors in context 1 of 3:
==6581== Invalid read of size 8
==6581==    at 0x10B9AE: cct_delete_parser (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A426: parse_file (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A320: main (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==  Address 0x4a16340 is 0 bytes inside a block of size 32 free'd
==6581==    at 0x48369AB: free (vg_replace_malloc.c:530)
==6581==    by 0x10B9A9: cct_delete_parser (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A426: parse_file (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A320: main (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==  Block was alloc'd at
==6581==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==6581==    by 0x10B94C: cct_new_parser (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A3A7: parse_file (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==    by 0x10A320: main (in /home/ldilley/projects/concoct/bld/bin/concoct)
==6581==
==6581== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

Added some print statements to show malloc() and free() calls (note the lack of freeing):

<18:42:43> (~/projects/concoct/bld)
[ldilley@genesis] :) {3004}$ bin/concoct ../src/tests/parser_test.cct
Concoct v0.1.0
Lexing ../src/tests/parser_test.cct:
[1] do : do
[1]  : {
[1]  : New line
[2] if : if
[2] Hello : String
[2]  : {
[2]  : New line
[3] for : for
[3] test : Identifier
[3] in : Token
[3] tests : Identifier
[3]  : {
[3]  : New line
[4] if : if
[4] test : Identifier
[4]  : {
[4]  : New line
[5] x : Identifier
[5]  : =
[5] 5 : Int
[5]  : New line
[6]  : }
[6]  : New line
[7]  : }
[7]  : New line
[8] msg : Identifier
[8]  : =
[8] Hello : String
[8]  : New line
[9]  : }
[9]  : New line
[10] y : Identifier
[10]  : =
[10] 3 : Int
[10]  : New line
[11]  : }
[11]  : New line
[12] while : while
[12] 5 : Int
node allocated!
node allocated!
node allocated!
node allocated!
node allocated!
text allocated!
child node allocated!
node allocated!
node allocated!
node allocated!
text allocated!
child node allocated!
node allocated!
text allocated!
child node allocated!
node allocated!
node allocated!
node allocated!
text allocated!
child node allocated!
node allocated!
node allocated!
text allocated!
node allocated!
child node allocated!
node allocated!
text allocated!
child node allocated!
child node allocated!
child node allocated!
child node allocated!
child node allocated!
child node allocated!
node allocated!
text allocated!
node allocated!
child node allocated!
node allocated!
text allocated!
child node allocated!
child node allocated!
child node allocated!
child node allocated!
node allocated!
text allocated!
node allocated!
child node allocated!
node allocated!
text allocated!
child node allocated!
child node allocated!
child node allocated!
node allocated!
text allocated!
child node allocated!
child node allocated!
New line ()
  do ()
    { ()
      if ()
        String (Hello)
        { ()
          for ()
            Identifier (test)
            Identifier (tests)
            { ()
              if ()
                Identifier (test)
                { ()
                  = ()
                    Identifier (x)
                    Int (5)
          = ()
            Identifier (msg)
            String (Hello)
      = ()
        Identifier (y)
        Int (3)
    Int (5)

Concoct Roadmap

Concoct Roadmap

  1. Draft language (keywords, operators, and syntax)
  2. Implement lexer
  3. Implement parser
  4. Draft opcodes/instruction set
  5. Implement stack-based (or register-based) VM (#19)
  6. Implement instructions (#32)
  7. Implement run-time options (#14)
  8. Handle semantics, scope, strings, flow control, expression evaluation, etc.
  9. Implement garbage collection (#18)
  10. Implement standard library constants, data structures (lists, hashmaps, etc.), and functions
  11. Ensure portability
  12. Implement super(classes), inheritance, and objects
  13. Bonus round: implement a compiler (using LLVM perhaps?)
  14. Refactor, optimize, test, and re-test

Allow expressions in the REPL

Feature Description

  • Allow expressions such as 1 + 2 or 1 > 0 in the REPL without an identifier and assignment operator. Currently, in interactive mode, the parser spits the following error rather than evaluate each expression (expected output below should be 3 and true):
> 1 + 2
Parsing error: [1] Expected a statement, got Int
> 1 > 0
Parsing error: [1] Expected a statement, got Int

Perhaps a relaxed mode could be added to cct_new_parser() when using a string lexer (and not file based).

Compiler runs if parser fails

Expected Behavior

  • a = ++++3 should not be permitted to reach the compile stage.

Actual Behavior/Symptoms

  • Compilation is attempted on a = ++++3 and similar invalid expressions.

How to Reproduce Behavior/Symptoms

  • Run concoct and input: a = ++++3

Concoct Version

  • 0.1.0

Compiler Version

  • Any

Operating System

  • Any

Output/Screenshot(s)

> a = ++++3
[1] a : Identifier
[1]  : =
[1]  : ++
[1]  : ++
[1] 3 : Int
Expression node is NULL!
Expression node is NULL!
Expression node is NULL!
Current relational expression node is NULL!
Current equality expression node is NULL!
Current bitwise AND expression node is NULL!
Current bitwise XOR expression node is NULL!
Current bitwise OR expression node is NULL!
Expression node is NULL!
Current OR expression node is NULL!
Parsing error: [1] Expected an expression, got ++
Debug: [08/08/2023 20:17:23 EDT (1691540243.966487) +/-3.541041] - Queue initialized with 256 slots.
Register values:
R0: empty
R1: empty
R2: empty
R3: empty
R4: empty
R5: empty
R6: empty
R7: empty
R8: empty
R9: empty
R10: empty
R11: empty
R12: empty
R13: empty
R14: empty
R15: empty
RS: empty
IP: OP_END (0x0B)
RP: 0x0
SP: empty

Freed parser
Freed node tree

Fix gcc compile warnings

The gcc compiler warnings below can be fixed by including ctype.h.

[ldilley@lindev] :) {4491}$ make
[  0%] Built target bindir
[ 33%] Building C object CMakeFiles/concoct.dir/src/concoct.c.o
[ 66%] Building C object CMakeFiles/concoct.dir/src/concoct_lexer.c.o
/home/ldilley/projects/concoct/src/concoct_lexer.c: In function ‘cct_next_token’:
/home/ldilley/projects/concoct/src/concoct_lexer.c:22:11: warning: implicit declaration of function ‘isspace’ [-Wimplicit-function-declaration]
     while(isspace(lexer->next_char))
           ^~~~~~~
/home/ldilley/projects/concoct/src/concoct_lexer.c:42:8: warning: implicit declaration of function ‘isalpha’ [-Wimplicit-function-declaration]
     if(isalpha(lexer->next_char) || lexer->next_char == '_')
        ^~~~~~~
/home/ldilley/projects/concoct/src/concoct_lexer.c:44:15: warning: implicit declaration of function ‘isalnum’ [-Wimplicit-function-declaration]
         while(isalnum(lexer->next_char) || lexer->next_char == '_')
               ^~~~~~~
/home/ldilley/projects/concoct/src/concoct_lexer.c:68:13: warning: implicit declaration of function ‘isdigit’ [-Wimplicit-function-declaration]
     else if(isdigit(lexer->next_char))
             ^~~~~~~
[100%] Linking C executable bin/concoct
[100%] Built target concoct

Change store threshold to percentage

Instead of a static integer for STORE_GROWTH_THRESHOLD (currently 8) use a dynamic percentage (10%). This value is the amount of store space remaining before a growth operation occurs.

Add object store size

Create a function to calculate object store size. This size value would consist of the total size of each object + string bytes occupied. The result can be converted to [kilo|mega|giga]bytes consumed. Also add a function to determine the number of occupied store slots (in contrast to the existing get_store_free_slots()).

Allow relational operators to compare string length

Feature Description

  • Allow >, <, >=, and <= to be used to compare string length.
  • Since == and != are already used to compare string value, create two new operators that will be used to compare the [in]equality of string length ($= and $!). These operators will simply behave as a shortcut (syntactic sugar) rather than requiring a call to a length function or accessing the length member of a string object.

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.