! 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 ]
[ "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", "" };
+*/
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
: 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 ;
: 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
{ "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 ;