123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- # This file is part of asmc, a bootstrapping OS with minimal seed
- # Copyright (C) 2018 Giovanni Mascellani <gio@debian.org>
- # https://gitlab.com/giomasce/asmc
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <https://www.gnu.org/licenses/>.
- const ASMCTX_FDIN 0
- const ASMCTX_READ_CHAR 4
- const ASMCTX_CHAR_GIVEN_BACK 8
- const ASMCTX_SYMBOLS 12
- const ASMCTX_STAGE 16
- const ASMCTX_CURRENT_LOC 20
- const ASMCTX_READ_TOKEN 24
- const ASMCTX_TOKEN_GIVEN_BACK 28
- const ASMCTX_VERBOSE 32
- const ASMCTX_DEBUG 36
- const SIZEOF_ASMCTX 40
- fun asmctx_init 0 {
- $ptr
- @ptr SIZEOF_ASMCTX malloc = ;
- ptr ASMCTX_SYMBOLS take_addr map_init = ;
- ptr ASMCTX_VERBOSE take_addr 1 = ;
- ptr ASMCTX_DEBUG take_addr 1 = ;
- ptr ret ;
- }
- fun asmctx_destroy 1 {
- $ptr
- @ptr 0 param = ;
- ptr ASMCTX_SYMBOLS take map_destroy ;
- ptr free ;
- }
- fun asmctx_emit 2 {
- $ctx
- $byte
- @ctx 1 param = ;
- @byte 0 param = ;
- if ctx ASMCTX_STAGE take 2 == {
- ctx ASMCTX_CURRENT_LOC take byte =c ;
- }
- ctx ASMCTX_CURRENT_LOC take_addr ctx ASMCTX_CURRENT_LOC take 1 + = ;
- }
- fun asmctx_emit16 2 {
- $ctx
- $word
- @ctx 1 param = ;
- @word 0 param = ;
- ctx word asmctx_emit ;
- ctx word 8 >> asmctx_emit ;
- }
- fun asmctx_emit32 2 {
- $ctx
- $dword
- @ctx 1 param = ;
- @dword 0 param = ;
- ctx dword asmctx_emit16 ;
- ctx dword 16 >> asmctx_emit16 ;
- }
- fun emit_size 3 {
- $ctx
- $data
- $size
- @ctx 2 param = ;
- @data 1 param = ;
- @size 0 param = ;
- if size 1 == {
- ctx data asmctx_emit ;
- } else {
- if size 2 == {
- ctx data asmctx_emit16 ;
- } else {
- if size 3 == {
- ctx data asmctx_emit32 ;
- } else {
- if size 4 == {
- ctx data asmctx_emit32 ;
- ctx 0 asmctx_emit32 ;
- } else {
- 0 "emit_size: invalid size" assert_msg ;
- }
- }
- }
- }
- }
- fun emit_multibyte 2 {
- $ctx
- $data
- @ctx 1 param = ;
- @data 0 param = ;
- if data 0xff & 1 == {
- ctx data 8 >> asmctx_emit ;
- ret ;
- }
- if data 0xff & 2 == {
- ctx data 8 >> asmctx_emit16 ;
- ret ;
- }
- if data 0xff & 3 == {
- ctx data 8 >> asmctx_emit ;
- ctx data 16 >> asmctx_emit16 ;
- ret ;
- }
- 0 "emit_multibyte: error 1" assert_msg ;
- }
- fun emit_string 2 {
- $ctx
- $str
- @ctx 1 param = ;
- @str 0 param = ;
- str **c '\'' == "emit_string: argument is not a string" assert_msg ;
- @str str 1 + = ;
- while str **c '\'' != {
- ctx str **c asmctx_emit ;
- @str str 1 + = ;
- }
- }
- fun asmctx_add_symbol 3 {
- $ctx
- $name
- $value
- @ctx 2 param = ;
- @name 1 param = ;
- @value 0 param = ;
- $syms
- @syms ctx ASMCTX_SYMBOLS take = ;
- if ctx ASMCTX_STAGE take 1 == {
- syms name map_has ! "asmctx_add_symbol: symbol already defined" assert_msg ;
- syms name value map_set ;
- }
- if ctx ASMCTX_STAGE take 2 == {
- syms name map_has "asmctx_add_symbol: error 1" assert_msg ;
- syms name map_at value == "asmctx_add_symbol: error 2" assert_msg ;
- }
- }
- fun asmctx_get_symbol 2 {
- $ctx
- $name
- @ctx 1 param = ;
- @name 0 param = ;
- $syms
- @syms ctx ASMCTX_SYMBOLS take = ;
- if ctx ASMCTX_STAGE take 2 == {
- if syms name map_has {
- syms name map_at ret ;
- } else {
- "Undefined symbol: " log ;
- name log ;
- "\n" log ;
- 0 "asmctx_get_symbol: symbol undefined" assert_msg ;
- }
- } else {
- 0 ret ;
- }
- }
- fun asmctx_get_symbol_addr 2 {
- $ctx
- $name
- @ctx 1 param = ;
- @name 0 param = ;
- $syms
- @syms ctx ASMCTX_SYMBOLS take = ;
- syms name map_has "asmctx_get_symbol_addr: symbol does not exist" assert_msg ;
- syms name map_at ret ;
- }
- fun asmctx_set_fd 2 {
- $ptr
- $fd
- @ptr 1 param = ;
- @fd 0 param = ;
- ptr ASMCTX_CHAR_GIVEN_BACK take_addr 0 = ;
- ptr ASMCTX_TOKEN_GIVEN_BACK take_addr 0 = ;
- ptr ASMCTX_FDIN take_addr fd = ;
- }
- # fun asmctx_set_starting_loc 2 {
- # $ptr
- # $loc
- # @ptr 1 param = ;
- # @loc 0 param = ;
- # ptr ASMCTX_CURRENT_LOC take_addr loc = ;
- # }
- fun asmctx_give_back_char 1 {
- $ctx
- @ctx 0 param = ;
- ctx ASMCTX_CHAR_GIVEN_BACK take ! "Character already given back" assert_msg ;
- ctx ASMCTX_CHAR_GIVEN_BACK take_addr 1 = ;
- }
- fun asmctx_get_char 1 {
- $ctx
- @ctx 0 param = ;
- if ctx ASMCTX_CHAR_GIVEN_BACK take {
- ctx ASMCTX_CHAR_GIVEN_BACK take_addr 0 = ;
- } else {
- ctx ASMCTX_READ_CHAR take_addr ctx ASMCTX_FDIN take vfs_read = ;
- }
- ctx ASMCTX_READ_CHAR take ret ;
- }
- fun asmctx_give_back_token 1 {
- $ctx
- @ctx 0 param = ;
- ctx ASMCTX_TOKEN_GIVEN_BACK take ! "Token already given back" assert_msg ;
- ctx ASMCTX_TOKEN_GIVEN_BACK take_addr 1 = ;
- }
- fun asmctx_get_token 1 {
- $ctx
- @ctx 0 param = ;
- if ctx ASMCTX_TOKEN_GIVEN_BACK take {
- ctx ASMCTX_TOKEN_GIVEN_BACK take_addr 0 = ;
- ctx ASMCTX_READ_TOKEN take ret ;
- }
- $token_buf
- $token_buf_len
- @token_buf_len 32 = ;
- @token_buf token_buf_len malloc = ;
- $state
- @state 0 = ;
- $token_type
- $token_len
- @token_len 0 = ;
- $cont
- @cont 1 = ;
- while cont {
- $c
- @c ctx asmctx_get_char = ;
- @cont c 0xffffffff != = ;
- if cont {
- $save_char
- @save_char 0 = ;
- $type
- @type c get_char_type = ;
- $enter_state
- @enter_state state = ;
- # Normal code
- if enter_state 0 == {
- @save_char 1 = ;
- }
- # Comment
- if enter_state 1 == {
- if c '\n' == {
- token_buf '\n' =c ;
- @token_len 1 = ;
- @state 0 = ;
- @cont 0 = ;
- }
- }
- # String
- if enter_state 2 == {
- @save_char 1 = ;
- #if c '\\' == {
- # @state 3 = ;
- #}
- if c '\'' == {
- @state 0 = ;
- @cont 0 = ;
- }
- }
- # String after backslash
- if enter_state 3 == {
- @save_char 1 = ;
- @state 2 = ;
- }
- token_buf token_len + c =c ;
- if save_char {
- if token_len 0 == {
- if type 2 != {
- @token_len token_len 1 + = ;
- @token_type type = ;
- if c '\'' == {
- @state 2 = ;
- @token_type 0 = ;
- }
- if c ';' == {
- @state 1 = ;
- @token_type 0 = ;
- }
- if token_type 1 == {
- @cont 0 = ;
- }
- if token_type 4 == {
- @cont 0 = ;
- }
- }
- } else {
- if token_type type == token_type 0 == || {
- @token_len token_len 1 + = ;
- } else {
- ctx asmctx_give_back_char ;
- @cont 0 = ;
- }
- }
- }
- if token_len 1 + token_buf_len >= {
- @token_buf_len token_buf_len 2 * = ;
- @token_buf token_buf_len token_buf realloc = ;
- }
- }
- }
- if token_type 2 == {
- token_buf ' ' =c ;
- @token_len 1 = ;
- }
- token_buf token_len + 0 =c ;
- ctx ASMCTX_READ_TOKEN take_addr token_buf = ;
- token_buf ret ;
- }
|