handle defines better, save all #if/#elif/#else/#pragma/#include_next. next step: tokenizing and macro replacement

db4
Doug Coleman 2009-04-02 11:39:18 -05:00
parent de357bacdb
commit 6399f4bc1a
2 changed files with 61 additions and 13 deletions

View File

@ -1,6 +1,6 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: tools.test c.preprocessor kernel accessors ;
USING: tools.test c.preprocessor kernel accessors multiline ;
IN: c.preprocessor.tests
[ "vocab:c/tests/test1/test1.c" start-preprocess-file ]
@ -9,8 +9,18 @@ IN: c.preprocessor.tests
[ "yo\n\n\n\nyo4\n" ]
[ "vocab:c/tests/test2/test2.c" start-preprocess-file nip ] unit-test
/*
[ "vocab:c/tests/test3/test3.c" start-preprocess-file ]
[ "\"BOO\"" = ] must-fail-with
*/
[ V{ "\"omg\"" "\"lol\"" } ]
[ "vocab:c/tests/test4/test4.c" start-preprocess-file drop warnings>> ] unit-test
/*
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
int i[] = { 1, 23, 4, 5, };
char c[2][6] = { "hello", "" };
*/

View File

@ -3,24 +3,41 @@
USING: html.parser.state io io.encodings.utf8 io.files
io.streams.string kernel combinators accessors io.pathnames
fry sequences arrays locals namespaces io.directories
assocs math splitting make ;
assocs math splitting make unicode.categories
combinators.short-circuit ;
IN: c.preprocessor
: initial-library-paths ( -- seq )
V{ "/usr/include" } clone ;
: initial-symbol-table ( -- hashtable )
H{
{ "__APPLE__" "" }
{ "__amd64__" "" }
{ "__x86_64__" "" }
} clone ;
TUPLE: preprocessor-state library-paths symbol-table
include-nesting include-nesting-max processing-disabled?
ifdef-nesting warnings ;
ifdef-nesting warnings errors
pragmas
include-nexts
ifs elifs elses ;
: <preprocessor-state> ( -- preprocessor-state )
preprocessor-state new
initial-library-paths >>library-paths
H{ } clone >>symbol-table
initial-symbol-table >>symbol-table
0 >>include-nesting
200 >>include-nesting-max
0 >>ifdef-nesting
V{ } clone >>warnings ;
V{ } clone >>warnings
V{ } clone >>errors
V{ } clone >>pragmas
V{ } clone >>include-nexts
V{ } clone >>ifs
V{ } clone >>elifs
V{ } clone >>elses ;
DEFER: preprocess-file
@ -64,8 +81,13 @@ ERROR: header-file-missing path ;
: readlns ( -- string ) [ (readlns) ] { } make concat ;
: take-define-identifier ( state-parser -- string )
skip-whitespace
[ current { [ blank? ] [ CHAR: ( = ] } 1|| ] take-until ;
: handle-define ( preprocessor-state state-parser -- )
[ take-token ] [ take-rest ] bi
[ take-define-identifier ]
[ skip-whitespace take-rest ] bi
"\\" ?tail [ readlns append ] when
spin symbol-table>> set-at ;
@ -86,9 +108,25 @@ ERROR: header-file-missing path ;
: handle-endif ( preprocessor-state state-parser -- )
drop [ 1 - ] change-ifdef-nesting drop ;
: handle-if ( preprocessor-state state-parser -- )
[ [ 1 + ] change-ifdef-nesting ] dip
skip-whitespace take-rest swap ifs>> push ;
: handle-elif ( preprocessor-state state-parser -- )
skip-whitespace take-rest swap elifs>> push ;
: handle-else ( preprocessor-state state-parser -- )
skip-whitespace take-rest swap elses>> push ;
: handle-pragma ( preprocessor-state state-parser -- )
skip-whitespace take-rest swap pragmas>> push ;
: handle-include-next ( preprocessor-state state-parser -- )
skip-whitespace take-rest swap include-nexts>> push ;
: handle-error ( preprocessor-state state-parser -- )
skip-whitespace
nip take-rest throw ;
skip-whitespace take-rest swap errors>> push ;
! nip take-rest throw ;
: handle-warning ( preprocessor-state state-parser -- )
skip-whitespace
@ -104,11 +142,11 @@ ERROR: header-file-missing path ;
{ "ifdef" [ handle-ifdef ] }
{ "ifndef" [ handle-ifndef ] }
{ "endif" [ handle-endif ] }
{ "if" [ 2drop ] }
{ "elif" [ 2drop ] }
{ "else" [ 2drop ] }
{ "pragma" [ 2drop ] }
{ "include_next" [ 2drop ] }
{ "if" [ handle-if ] }
{ "elif" [ handle-elif ] }
{ "else" [ handle-else ] }
{ "pragma" [ handle-pragma ] }
{ "include_next" [ handle-include-next ] }
[ unknown-c-preprocessor ]
} case ;