duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit e705cf3935d68404241c324272bfa8866786a711
parent 85bac318cea174ff197ba4ad71333d79e9eb3046
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Tue, 21 Jun 2022 21:21:09 -0400

cc: add support for array assignment

int a[3] = {1, 2, 3};

Diffstat:
Mfs/cc/ast.fs | 26+++++++++++++++++++++++---
Mfs/cc/gen.fs | 8+++++++-
Mfs/cc/vm.fs | 11++++++++++-
Mfs/tests/cc/test.c | 5+----
4 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/fs/cc/ast.fs b/fs/cc/ast.fs @@ -46,14 +46,14 @@ create bopsprectbl 1 c, 1 c, 0 c, 0 c, 2 c, 2 c, 2 c, 2 c, 8 const AST_UNARYOP \ data1=uopid 9 const AST_POSTFIXOP \ data1=popid 10 const AST_BINARYOP \ data1=bopid -\ 11 = unused +11 const AST_LIST \ list of lvalues or constants: {1, 2, 3} 12 const AST_IF \ 13 = unused 14 const AST_FUNCALL \ data1=name data2=MAP_FUNCTION ASTIDCNT stringlist astidnames "declare" "unit" "function" "return" "constant" "stmts" "args" "lvalue" -"unaryop" "postop" "binop" "_" "if" "_" "call" +"unaryop" "postop" "binop" "list" "if" "_" "call" 0 value curunit \ points to current Unit, the beginning of the AST @@ -121,6 +121,23 @@ ASTIDCNT wordtbl astdatatbl ( node -- node ) alias noop parseExpression ( tok -- node ) \ forward declaration +\ The first '{' has already been read +: parseList ( -- node ) + AST_LIST createnode nextt dup S" }" s= if drop exit then + begin ( lnode tok ) case + of isIdent? ( lnode ) + AST_LVALUE createnode swap , ( lnode lvnode ) over addnode endof + of parse ( lnode n ) + AST_CONSTANT createnode swap , ( lnode cnode ) over addnode endof + _err + endcase + nextt case + S" }" of s= r~ exit endof + S" ," of s= endof + _err + endcase + nextt again ; + : parsePostfixOp ( tok lvnode -- node ) over S" [" s= if ( tok lvnode ) \ x[y] is the equivalent of *(x+y) nip AST_BINARYOP createnode 0 ( + ) , ( lvnode bnode ) @@ -210,7 +227,10 @@ current to parseExpression drop ( dnode ) dup data1 ( dnode name ) swap parentnode AST_BINARYOP newnode ( name anode ) 12 ( = ) , AST_LVALUE newnode ( name lvnode ) swap , parentnode ( anode ) - nextt parseExpression read; ( anode expr ) swap addnode ; + nextt dup S" {" s= if + drop parseList else + parseExpression then + read; ( anode expr-or-list ) swap addnode ; : parseArgSpecs ( funcnode -- ) nextt '(' expectChar AST_ARGSPECS newnode nextt ( argsnode tok ) diff --git a/fs/cc/gen.fs b/fs/cc/gen.fs @@ -177,7 +177,13 @@ ASTIDCNT wordtbl gentbl ( node -- ) selop1 gennode selop2 gennode then bopgentblpost r> data1 wexec r> ( selectedop ) if op1<>op2 else selop1 then ; -'w _err ( unused ) +\ TODO: this doesn't work with lvalues yet +:w ( List ) + dup childcount dup 1+ 4 * scratchallot dup >r ( node len a ) + over >r tuck ! 4 + swap firstchild begin ( a node ) + dup data1 ( a node value ) rot tuck ! ( node a ) + 4 + swap nextsibling next ( a node ) 2drop + r> constarray>op ; :w ( If ) firstchild ?dup not if _err then dup gennode ( exprnode ) vmjz, swap ( jump_addr exprnode ) ops$ diff --git a/fs/cc/vm.fs b/fs/cc/vm.fs @@ -77,6 +77,7 @@ $00 const VM_NONE $01 const VM_CONSTANT \ 42 $02 const VM_STACKFRAME \ ebp+x $03 const VM_REGISTER \ eax +$11 const VM_CONSTARRAY \ pointer to an array with the 1st elem being length $12 const VM_*STACKFRAME \ [ebp+x] $13 const VM_*REGISTER \ [eax] @@ -108,6 +109,7 @@ operands value 'curop : hasop# optype VM_NONE = not _assert ; : noop# optype VM_NONE = _assert ; : const>op ( n -- ) noop# VM_CONSTANT optype! oparg! ; +: constarray>op ( a -- ) noop# VM_CONSTARRAY optype! oparg! ; : sf+>op ( off -- ) noop# VM_*STACKFRAME optype! oparg! ; \ get current operand SF offset, adjusted with callsz @@ -223,7 +225,14 @@ operands value 'curop \ op2. In other words, perform a AST_ASSIGN with the right part as op2 \ and the left part as op1. : vmmov, - maybederef selop1 opAsm selop2 opAsm mov, opdeinit ; + selop2 optype VM_CONSTARRAY = if \ special case, we have a {1, 2, 3} assign + selop1 optype VM_STACKFRAME = _assert + *op>op selop2 oparg selop1 dup @ ( a len ) >r begin ( a ) + opAsm 4 + dup @ i32 mov, ( a+4 ) oparg 4 + oparg! next ( a ) + drop selop2 + else + maybederef selop1 opAsm selop2 opAsm mov, then + opdeinit ; \ Code generation - Unary ops diff --git a/fs/tests/cc/test.c b/fs/tests/cc/test.c @@ -63,9 +63,6 @@ int* ptrari(int *x) { return x + 1; } int array() { - int a[3]; - *a = 42; - *(a+1) = 12; - a[2] = 2; + int a[3] = {42, 12, 2}; return *a + a[1] - *(a+2); }