Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
P
preprocessor
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Normann Rion
preprocessor
Commits
8ebd2a17
Verified
Commit
8ebd2a17
authored
Aug 19, 2019
by
Houtan Bastani
Browse files
Options
Downloads
Patches
Plain Diff
macro processor: support `@#elseif` directive
parent
75b000a0
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
src/macro/Directives.cc
+42
-50
42 additions, 50 deletions
src/macro/Directives.cc
src/macro/Directives.hh
+8
-30
8 additions, 30 deletions
src/macro/Directives.hh
src/macro/Parser.yy
+63
-46
63 additions, 46 deletions
src/macro/Parser.yy
src/macro/Tokenizer.ll
+1
-0
1 addition, 0 deletions
src/macro/Tokenizer.ll
with
114 additions
and
126 deletions
src/macro/Directives.cc
+
42
−
50
View file @
8ebd2a17
...
@@ -210,14 +210,19 @@ For::interpret(ostream &output, bool no_line_macro)
...
@@ -210,14 +210,19 @@ For::interpret(ostream &output, bool no_line_macro)
void
void
If
::
interpret
(
ostream
&
output
,
bool
no_line_macro
)
If
::
interpret
(
ostream
&
output
,
bool
no_line_macro
)
{
{
RealPtr
dp
;
for
(
auto
&
it
:
expr_and_body
)
BoolPtr
bp
;
try
try
{
{
dp
=
dynamic_pointer_cast
<
Real
>
(
condition
->
eval
());
RealPtr
dp
=
dynamic_pointer_cast
<
Real
>
(
it
.
first
->
eval
());
bp
=
dynamic_pointer_cast
<
Bool
>
(
condition
->
eval
());
BoolPtr
bp
=
dynamic_pointer_cast
<
Bool
>
(
it
.
first
->
eval
());
if
(
!
bp
&&
!
dp
)
if
(
!
bp
&&
!
dp
)
error
(
StackTrace
(
"@#if"
,
"The condition must evaluate to a boolean or a double"
,
location
));
error
(
StackTrace
(
"@#if"
,
"The condition must evaluate to a boolean or a double"
,
location
));
if
((
bp
&&
*
bp
)
||
(
dp
&&
*
dp
))
{
interpretBody
(
it
.
second
,
output
,
no_line_macro
);
break
;
}
}
}
catch
(
StackTrace
&
ex
)
catch
(
StackTrace
&
ex
)
{
{
...
@@ -228,19 +233,14 @@ If::interpret(ostream &output, bool no_line_macro)
...
@@ -228,19 +233,14 @@ If::interpret(ostream &output, bool no_line_macro)
{
{
error
(
StackTrace
(
"@#if"
,
e
.
what
(),
location
));
error
(
StackTrace
(
"@#if"
,
e
.
what
(),
location
));
}
}
if
((
bp
&&
*
bp
)
||
(
dp
&&
*
dp
))
loopIf
(
output
,
no_line_macro
);
else
loopElse
(
output
,
no_line_macro
);
printEndLineInfo
(
output
,
no_line_macro
);
printEndLineInfo
(
output
,
no_line_macro
);
}
}
void
void
If
::
loopIf
(
ostream
&
output
,
bool
no_line_macro
)
If
::
interpretBody
(
const
vector
<
DirectivePtr
>
&
body
,
ostream
&
output
,
bool
no_line_macro
)
{
{
bool
printLine
=
!
no_line_macro
;
bool
printLine
=
!
no_line_macro
;
for
(
auto
&
statement
:
if_statements
)
for
(
auto
&
statement
:
body
)
{
{
if
(
printLine
)
if
(
printLine
)
{
{
...
@@ -252,41 +252,33 @@ If::loopIf(ostream &output, bool no_line_macro)
...
@@ -252,41 +252,33 @@ If::loopIf(ostream &output, bool no_line_macro)
}
}
void
void
If
::
loopElse
(
ostream
&
output
,
bool
no_line_macro
)
If
def
::
interpret
(
ostream
&
output
,
bool
no_line_macro
)
{
{
bool
printLine
=
!
no_line_macro
;
for
(
auto
&
it
:
expr_and_body
)
for
(
auto
&
statement
:
else_statements
)
{
{
if
(
printLine
)
VariablePtr
vp
=
dynamic_pointer_cast
<
Variable
>
(
it
.
first
);
if
(
dynamic_pointer_cast
<
BaseType
>
(
it
.
first
)
||
(
vp
&&
env
.
isVariableDefined
(
vp
->
getName
())))
{
{
statement
->
printLineInfo
(
output
,
no_line_macro
);
interpretBody
(
it
.
second
,
output
,
no_line_macro
);
printLine
=
false
;
break
;
}
statement
->
interpret
(
output
,
no_line_macro
);
}
}
}
}
void
Ifdef
::
interpret
(
ostream
&
output
,
bool
no_line_macro
)
{
BaseTypePtr
btnp
=
dynamic_pointer_cast
<
BaseType
>
(
condition
);
VariablePtr
vp
=
dynamic_pointer_cast
<
Variable
>
(
condition
);
if
(
btnp
||
(
vp
&&
env
.
isVariableDefined
(
vp
->
getName
())))
loopIf
(
output
,
no_line_macro
);
else
loopElse
(
output
,
no_line_macro
);
printEndLineInfo
(
output
,
no_line_macro
);
printEndLineInfo
(
output
,
no_line_macro
);
}
}
void
void
Ifndef
::
interpret
(
ostream
&
output
,
bool
no_line_macro
)
Ifndef
::
interpret
(
ostream
&
output
,
bool
no_line_macro
)
{
{
BaseTypePtr
btnp
=
dynamic_pointer_cast
<
BaseType
>
(
condition
);
for
(
auto
&
it
:
expr_and_body
)
VariablePtr
vp
=
dynamic_pointer_cast
<
Variable
>
(
condition
);
{
if
(
!
(
btnp
||
(
vp
&&
env
.
isVariableDefined
(
vp
->
getName
()))))
VariablePtr
vp
=
dynamic_pointer_cast
<
Variable
>
(
it
.
first
);
loopIf
(
output
,
no_line_macro
);
if
(
!
(
dynamic_pointer_cast
<
BaseType
>
(
it
.
first
)
else
||
(
vp
&&
env
.
isVariableDefined
(
vp
->
getName
()))))
loopElse
(
output
,
no_line_macro
);
{
interpretBody
(
it
.
second
,
output
,
no_line_macro
);
break
;
}
}
printEndLineInfo
(
output
,
no_line_macro
);
printEndLineInfo
(
output
,
no_line_macro
);
}
}
This diff is collapsed.
Click to expand it.
src/macro/Directives.hh
+
8
−
30
View file @
8ebd2a17
...
@@ -163,39 +163,23 @@ namespace macro
...
@@ -163,39 +163,23 @@ namespace macro
class
If
:
public
Directive
class
If
:
public
Directive
{
{
protected:
protected:
const
ExpressionPtr
condition
;
const
vector
<
pair
<
ExpressionPtr
,
vector
<
DirectivePtr
>>>
expr_and_body
;
const
vector
<
DirectivePtr
>
if_statements
;
const
vector
<
DirectivePtr
>
else_statements
;
public:
public:
If
(
ExpressionPtr
condition_arg
,
If
(
vector
<
pair
<
ExpressionPtr
,
vector
<
DirectivePtr
>>>
expr_and_body_arg
,
vector
<
DirectivePtr
>
if_statements_arg
,
Environment
&
env_arg
,
Tokenizer
::
location
location_arg
)
:
Environment
&
env_arg
,
Tokenizer
::
location
location_arg
)
:
Directive
(
env_arg
,
move
(
location_arg
)),
condition
{
move
(
condition_arg
)},
if_statements
{
move
(
if_statements_arg
)}
{
}
Directive
(
env_arg
,
move
(
location_arg
)),
expr_and_body
{
move
(
expr_and_body_arg
)}
{
}
If
(
ExpressionPtr
condition_arg
,
vector
<
DirectivePtr
>
if_statements_arg
,
vector
<
DirectivePtr
>
else_statements_arg
,
Environment
&
env_arg
,
Tokenizer
::
location
location_arg
)
:
Directive
(
env_arg
,
move
(
location_arg
)),
condition
{
move
(
condition_arg
)},
if_statements
{
move
(
if_statements_arg
)},
else_statements
{
move
(
else_statements_arg
)}
{
}
void
interpret
(
ostream
&
output
,
bool
no_line_macro
)
override
;
void
interpret
(
ostream
&
output
,
bool
no_line_macro
)
override
;
protected
:
protected
:
void
loopIf
(
ostream
&
output
,
bool
no_line_macro
);
void
interpretBody
(
const
vector
<
DirectivePtr
>
&
body
,
ostream
&
output
,
bool
no_line_macro
);
void
loopElse
(
ostream
&
output
,
bool
no_line_macro
);
};
};
class
Ifdef
:
public
If
class
Ifdef
:
public
If
{
{
public:
public:
Ifdef
(
ExpressionPtr
condition_arg
,
Ifdef
(
vector
<
pair
<
ExpressionPtr
,
vector
<
DirectivePtr
>>>
expr_and_body_arg
,
vector
<
DirectivePtr
>
if_statements_arg
,
Environment
&
env_arg
,
Tokenizer
::
location
location_arg
)
:
If
(
move
(
condition_arg
),
move
(
if_statements_arg
),
env_arg
,
move
(
location_arg
))
{
}
Ifdef
(
ExpressionPtr
condition_arg
,
vector
<
DirectivePtr
>
if_statements_arg
,
vector
<
DirectivePtr
>
else_statements_arg
,
Environment
&
env_arg
,
Tokenizer
::
location
location_arg
)
:
Environment
&
env_arg
,
Tokenizer
::
location
location_arg
)
:
If
(
move
(
condition_arg
),
move
(
if_statements_arg
),
move
(
else_statements
_arg
),
env_arg
,
move
(
location_arg
))
{
}
If
(
move
(
expr_and_body
_arg
),
env_arg
,
move
(
location_arg
))
{
}
void
interpret
(
ostream
&
output
,
bool
no_line_macro
)
override
;
void
interpret
(
ostream
&
output
,
bool
no_line_macro
)
override
;
};
};
...
@@ -203,15 +187,9 @@ namespace macro
...
@@ -203,15 +187,9 @@ namespace macro
class
Ifndef
:
public
If
class
Ifndef
:
public
If
{
{
public:
public:
Ifndef
(
ExpressionPtr
condition_arg
,
Ifndef
(
vector
<
pair
<
ExpressionPtr
,
vector
<
DirectivePtr
>>>
expr_and_body_arg
,
vector
<
DirectivePtr
>
if_statements_arg
,
Environment
&
env_arg
,
Tokenizer
::
location
location_arg
)
:
If
(
move
(
condition_arg
),
move
(
if_statements_arg
),
env_arg
,
move
(
location_arg
))
{
}
Ifndef
(
ExpressionPtr
condition_arg
,
vector
<
DirectivePtr
>
if_statements_arg
,
vector
<
DirectivePtr
>
else_statements_arg
,
Environment
&
env_arg
,
Tokenizer
::
location
location_arg
)
:
Environment
&
env_arg
,
Tokenizer
::
location
location_arg
)
:
If
(
move
(
condition_arg
),
move
(
if_statements_arg
),
move
(
else_statements
_arg
),
env_arg
,
move
(
location_arg
))
{
}
If
(
move
(
expr_and_body
_arg
),
env_arg
,
move
(
location_arg
))
{
}
void
interpret
(
ostream
&
output
,
bool
no_line_macro
)
override
;
void
interpret
(
ostream
&
output
,
bool
no_line_macro
)
override
;
};
};
}
}
...
...
This diff is collapsed.
Click to expand it.
src/macro/Parser.yy
+
63
−
46
View file @
8ebd2a17
...
@@ -56,7 +56,7 @@ using namespace macro;
...
@@ -56,7 +56,7 @@ using namespace macro;
}
}
%token FOR ENDFOR IF IFDEF IFNDEF ELSE ENDIF TRUE FALSE
%token FOR ENDFOR IF IFDEF IFNDEF
ELSEIF
ELSE ENDIF TRUE FALSE
%token INCLUDE INCLUDEPATH DEFINE EQUAL D_ECHO ERROR
%token INCLUDE INCLUDEPATH DEFINE EQUAL D_ECHO ERROR
%token COMMA LPAREN RPAREN LBRACKET RBRACKET WHEN
%token COMMA LPAREN RPAREN LBRACKET RBRACKET WHEN
%token BEGIN_EVAL END_EVAL ECHOMACROVARS SAVE
%token BEGIN_EVAL END_EVAL ECHOMACROVARS SAVE
...
@@ -91,6 +91,8 @@ using namespace macro;
...
@@ -91,6 +91,8 @@ using namespace macro;
%type <DirectivePtr> statement
%type <DirectivePtr> statement
%type <DirectivePtr> directive directive_one_line directive_multiline for if ifdef ifndef text eval
%type <DirectivePtr> directive directive_one_line directive_multiline for if ifdef ifndef text eval
%type <vector<pair<ExpressionPtr, vector<DirectivePtr>>>> if_list if_list1
%type <pair<ExpressionPtr, vector<DirectivePtr>>> elseif else
%type <ExpressionPtr> primary_expr oper_expr colon_expr expr
%type <ExpressionPtr> primary_expr oper_expr colon_expr expr
%type <FunctionPtr> function
%type <FunctionPtr> function
%type <VariablePtr> symbol
%type <VariablePtr> symbol
...
@@ -176,60 +178,75 @@ comma_name : NAME
...
@@ -176,60 +178,75 @@ comma_name : NAME
{ $1.emplace_back(make_shared<Variable>($3, driver.env, @3)); $$ = $1; }
{ $1.emplace_back(make_shared<Variable>($3, driver.env, @3)); $$ = $1; }
;
;
if_begin : IF { driver.pushContext(); }
if : IF { driver.pushContext(); } if_list ENDIF
{ $$ = make_shared<If>($3, driver.env, @$); }
;
ifdef : IFDEF { driver.pushContext(); } if_list ENDIF
{ $$ = make_shared<Ifdef>($3, driver.env, @$); }
;
;
if : if_begin expr EOL statements ENDIF
ifndef : IFNDEF { driver.pushContext(); } if_list ENDIF
{ $$ = make_shared<Ifndef>($3, driver.env, @$); }
;
if_list : if_list1
| if_list1 else
{
{
auto ifContext = driver.popContext();
$1.emplace_back($2);
ifContext.emplace_back(make_shared<TextNode>("\n", driver.env, @5));
$$ = $1;
$$ = make_shared<If>($2, ifContext, driver.env, @$);
}
}
| if_begin expr EOL statements ELSE EOL { driver.pushContext(); } statements ENDIF
;
if_list1 : expr EOL
{
{
auto elseContext = driver.popContext();
auto context = driver.popContext();
elseContext.emplace_back(make_shared<TextNode>("\n", driver.env, @9));
context.emplace_back(make_shared<TextNode>("\n", driver.env, @2));
auto ifContext = driver.popContext();
$$ = vector<pair<ExpressionPtr, vector<DirectivePtr>>> { make_pair($1, context) };
ifContext.emplace_back(make_shared<TextNode>("\n", driver.env, @5));
}
$$ = make_shared<If>($2, ifContext, elseContext, driver.env, @$);
| expr EOL statements
{
auto context = driver.popContext();
context.emplace_back(make_shared<TextNode>("\n", driver.env, @3));
$$ = vector<pair<ExpressionPtr, vector<DirectivePtr>>> { make_pair($1, context) };
}
| if_list1 elseif
{
$1.emplace_back($2);
$$ = $1;
}
}
;
;
ifdef_begin : IFDEF { driver.pushContext(); }
elseif_begin : ELSEIF { driver.pushContext(); } ;
;
ifdef : ifde
f_begin expr EOL
statements ENDIF
elseif : elsei
f_begin expr EOL
{
{
auto
ifC
ontext = driver.popContext();
auto
c
ontext = driver.popContext();
ifC
ontext.emplace_back(make_shared<TextNode>("\n", driver.env, @
5
));
c
ontext.emplace_back(make_shared<TextNode>("\n", driver.env, @
3
));
$$ = make_
shared<Ifdef>
($2,
ifC
ontext
, driver.env, @$
);
$$ = make_
pair
($2,
c
ontext);
}
}
|
ifde
f_begin expr EOL statements
ELSE EOL { driver.pushContext(); } statements ENDIF
|
elsei
f_begin expr EOL statements
{
{
auto elseContext = driver.popContext();
auto context = driver.popContext();
elseContext.emplace_back(make_shared<TextNode>("\n", driver.env, @9));
context.emplace_back(make_shared<TextNode>("\n", driver.env, @4));
auto ifContext = driver.popContext();
$$ = make_pair($2, context);
ifContext.emplace_back(make_shared<TextNode>("\n", driver.env, @5));
$$ = make_shared<Ifdef>($2, ifContext, elseContext, driver.env, @$);
}
}
;
;
ifndef_begin : IFNDEF { driver.pushContext(); }
else_begin : ELSE { driver.pushContext(); } ;
;
ifndef : ifndef_begin expr EOL statements ENDIF
else : else_begin EOL
{
{
auto
ifC
ontext = driver.popContext();
auto
c
ontext = driver.popContext();
ifC
ontext.emplace_back(make_shared<TextNode>("\n", driver.env, @
5
));
c
ontext.emplace_back(make_shared<TextNode>("\n", driver.env, @
2
));
$$ = make_shared<
Ifndef>($2, ifContext
, driver.env, @
$
);
$$ =
make_pair(
make_shared<
Bool>(true
, driver.env, @
1), context
);
}
}
| ifndef
_begin
expr
EOL statements
ELSE EOL { driver.pushContext(); } statements ENDIF
| else
_begin EOL statements
{
{
auto elseContext = driver.popContext();
auto context = driver.popContext();
elseContext.emplace_back(make_shared<TextNode>("\n", driver.env, @9));
context.emplace_back(make_shared<TextNode>("\n", driver.env, @3));
auto ifContext = driver.popContext();
$$ = make_pair(make_shared<Bool>(true, driver.env, @1), context);
ifContext.emplace_back(make_shared<TextNode>("\n", driver.env, @5));
$$ = make_shared<Ifndef>($2, ifContext, elseContext, driver.env, @$);
}
}
;
;
...
...
This diff is collapsed.
Click to expand it.
src/macro/Tokenizer.ll
+
1
−
0
View file @
8ebd2a17
...
@@ -72,6 +72,7 @@ CONT \\\\{SPC}*
...
@@ -72,6 +72,7 @@ CONT \\\\{SPC}*
<
directive
>
if
{
BEGIN
(
expr
)
; return token::IF; }
<
directive
>
if
{
BEGIN
(
expr
)
; return token::IF; }
<
directive
>
ifdef
{
BEGIN
(
expr
)
; return token::IFDEF; }
<
directive
>
ifdef
{
BEGIN
(
expr
)
; return token::IFDEF; }
<
directive
>
ifndef
{
BEGIN
(
expr
)
; return token::IFNDEF; }
<
directive
>
ifndef
{
BEGIN
(
expr
)
; return token::IFNDEF; }
<
directive
>
elseif
{
BEGIN
(
expr
)
; return token::ELSEIF; }
<
directive
>
else
{
BEGIN
(
end_line
)
; return token::ELSE; }
<
directive
>
else
{
BEGIN
(
end_line
)
; return token::ELSE; }
<
directive
>
endif
{
BEGIN
(
end_line
)
; return token::ENDIF; }
<
directive
>
endif
{
BEGIN
(
end_line
)
; return token::ENDIF; }
<
directive
>
for
{
BEGIN
(
expr
)
; return token::FOR; }
<
directive
>
for
{
BEGIN
(
expr
)
; return token::FOR; }
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment