Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
node-sass
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
楚学文
node-sass
Commits
bbd04d5e
Commit
bbd04d5e
authored
May 28, 2012
by
Aaron Leung
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moving selector expansion into the eval phase. Necessary for inheritance.
parent
d7502ac1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
178 additions
and
47 deletions
+178
-47
eval_apply.cpp
eval_apply.cpp
+149
-40
eval_apply.hpp
eval_apply.hpp
+6
-3
sass_interface.cpp
sass_interface.cpp
+6
-1
test_node_factory.cpp
test_node_factory.cpp
+17
-3
No files found.
eval_apply.cpp
View file @
bbd04d5e
...
@@ -17,7 +17,7 @@ namespace Sass {
...
@@ -17,7 +17,7 @@ namespace Sass {
throw
Error
(
Error
::
evaluation
,
path
,
line
,
message
);
throw
Error
(
Error
::
evaluation
,
path
,
line
,
message
);
}
}
Node
eval
(
Node
expr
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
ctx
)
Node
eval
(
Node
expr
,
Node
prefix
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
ctx
)
{
{
switch
(
expr
.
type
())
switch
(
expr
.
type
())
{
{
...
@@ -31,7 +31,7 @@ namespace Sass {
...
@@ -31,7 +31,7 @@ namespace Sass {
Node
args
(
expr
[
1
]);
Node
args
(
expr
[
1
]);
if
(
!
env
.
query
(
name
))
throw_eval_error
(
"mixin "
+
name
.
to_string
()
+
" is undefined"
,
expr
.
path
(),
expr
.
line
());
if
(
!
env
.
query
(
name
))
throw_eval_error
(
"mixin "
+
name
.
to_string
()
+
" is undefined"
,
expr
.
path
(),
expr
.
line
());
Node
mixin
(
env
[
name
]);
Node
mixin
(
env
[
name
]);
Node
expansion
(
apply_mixin
(
mixin
,
args
,
env
,
f_env
,
new_Node
,
ctx
));
Node
expansion
(
apply_mixin
(
mixin
,
args
,
prefix
,
env
,
f_env
,
new_Node
,
ctx
));
expr
.
pop_back
();
expr
.
pop_back
();
expr
.
pop_back
();
expr
.
pop_back
();
expr
+=
expansion
;
expr
+=
expansion
;
...
@@ -39,25 +39,27 @@ namespace Sass {
...
@@ -39,25 +39,27 @@ namespace Sass {
}
break
;
}
break
;
case
Node
:
:
propset
:
{
case
Node
:
:
propset
:
{
eval
(
expr
[
1
],
env
,
f_env
,
new_Node
,
ctx
);
eval
(
expr
[
1
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
return
expr
;
return
expr
;
}
break
;
}
break
;
case
Node
:
:
ruleset
:
{
case
Node
:
:
ruleset
:
{
// if the selector contains interpolants, eval it and re-parse
if
(
expr
[
0
].
type
()
==
Node
::
selector_schema
)
{
if
(
expr
[
0
].
type
()
==
Node
::
selector_schema
)
{
expr
[
0
]
=
eval
(
expr
[
0
],
env
,
f_env
,
new_Node
,
ctx
);
expr
[
0
]
=
eval
(
expr
[
0
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
// expand the selector right here and stick it in expr[2]
// expand the selector with the prefix and save it in expr[2]
expr
<<
expand_selector
(
expr
[
0
],
prefix
,
new_Node
);
// cerr << "EXPANDED SELECTOR: " << expr.back().to_string("") << endl;
eval
(
expr
[
1
],
env
,
f_env
,
new_Node
,
ctx
);
// eval the body with the current selector as the prefix
eval
(
expr
[
1
],
expr
[
0
],
env
,
f_env
,
new_Node
,
ctx
);
return
expr
;
return
expr
;
}
break
;
}
break
;
case
Node
:
:
selector_schema
:
{
case
Node
:
:
selector_schema
:
{
string
expansion
;
string
expansion
;
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
expr
[
i
]
=
eval
(
expr
[
i
],
env
,
f_env
,
new_Node
,
ctx
);
expr
[
i
]
=
eval
(
expr
[
i
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
if
(
expr
[
i
].
type
()
==
Node
::
string_constant
)
{
if
(
expr
[
i
].
type
()
==
Node
::
string_constant
)
{
expansion
+=
expr
[
i
].
token
().
unquote
();
expansion
+=
expr
[
i
].
token
().
unquote
();
}
}
...
@@ -76,7 +78,7 @@ namespace Sass {
...
@@ -76,7 +78,7 @@ namespace Sass {
case
Node
:
:
root
:
{
case
Node
:
:
root
:
{
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
eval
(
expr
[
i
],
env
,
f_env
,
new_Node
,
ctx
);
eval
(
expr
[
i
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
return
expr
;
return
expr
;
}
break
;
}
break
;
...
@@ -85,7 +87,7 @@ namespace Sass {
...
@@ -85,7 +87,7 @@ namespace Sass {
Environment
new_frame
;
Environment
new_frame
;
new_frame
.
link
(
env
);
new_frame
.
link
(
env
);
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
eval
(
expr
[
i
],
new_frame
,
f_env
,
new_Node
,
ctx
);
eval
(
expr
[
i
],
prefix
,
new_frame
,
f_env
,
new_Node
,
ctx
);
}
}
return
expr
;
return
expr
;
}
break
;
}
break
;
...
@@ -94,11 +96,11 @@ namespace Sass {
...
@@ -94,11 +96,11 @@ namespace Sass {
Node
val
(
expr
[
1
]);
Node
val
(
expr
[
1
]);
if
(
val
.
type
()
==
Node
::
comma_list
||
val
.
type
()
==
Node
::
space_list
)
{
if
(
val
.
type
()
==
Node
::
comma_list
||
val
.
type
()
==
Node
::
space_list
)
{
for
(
size_t
i
=
0
,
S
=
val
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
i
=
0
,
S
=
val
.
size
();
i
<
S
;
++
i
)
{
if
(
val
[
i
].
should_eval
())
val
[
i
]
=
eval
(
val
[
i
],
env
,
f_env
,
new_Node
,
ctx
);
if
(
val
[
i
].
should_eval
())
val
[
i
]
=
eval
(
val
[
i
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
}
}
else
{
else
{
val
=
eval
(
val
,
env
,
f_env
,
new_Node
,
ctx
);
val
=
eval
(
val
,
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
Node
var
(
expr
[
0
]);
Node
var
(
expr
[
0
]);
if
(
env
.
query
(
var
.
token
()))
{
if
(
env
.
query
(
var
.
token
()))
{
...
@@ -114,28 +116,28 @@ namespace Sass {
...
@@ -114,28 +116,28 @@ namespace Sass {
Node
rhs
(
expr
[
1
]);
Node
rhs
(
expr
[
1
]);
if
(
rhs
.
type
()
==
Node
::
comma_list
||
rhs
.
type
()
==
Node
::
space_list
)
{
if
(
rhs
.
type
()
==
Node
::
comma_list
||
rhs
.
type
()
==
Node
::
space_list
)
{
for
(
size_t
i
=
0
,
S
=
rhs
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
i
=
0
,
S
=
rhs
.
size
();
i
<
S
;
++
i
)
{
if
(
rhs
[
i
].
should_eval
())
rhs
[
i
]
=
eval
(
rhs
[
i
],
env
,
f_env
,
new_Node
,
ctx
);
if
(
rhs
[
i
].
should_eval
())
rhs
[
i
]
=
eval
(
rhs
[
i
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
}
}
else
if
(
rhs
.
type
()
==
Node
::
value_schema
||
rhs
.
type
()
==
Node
::
string_schema
)
{
else
if
(
rhs
.
type
()
==
Node
::
value_schema
||
rhs
.
type
()
==
Node
::
string_schema
)
{
eval
(
rhs
,
env
,
f_env
,
new_Node
,
ctx
);
eval
(
rhs
,
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
else
{
else
{
if
(
rhs
.
should_eval
())
expr
[
1
]
=
eval
(
rhs
,
env
,
f_env
,
new_Node
,
ctx
);
if
(
rhs
.
should_eval
())
expr
[
1
]
=
eval
(
rhs
,
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
return
expr
;
return
expr
;
}
break
;
}
break
;
case
Node
:
:
comma_list
:
case
Node
:
:
comma_list
:
case
Node
:
:
space_list
:
{
case
Node
:
:
space_list
:
{
if
(
expr
.
should_eval
())
expr
[
0
]
=
eval
(
expr
[
0
],
env
,
f_env
,
new_Node
,
ctx
);
if
(
expr
.
should_eval
())
expr
[
0
]
=
eval
(
expr
[
0
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
return
expr
;
return
expr
;
}
break
;
}
break
;
case
Node
:
:
disjunction
:
{
case
Node
:
:
disjunction
:
{
Node
result
;
Node
result
;
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
result
=
eval
(
expr
[
i
],
env
,
f_env
,
new_Node
,
ctx
);
result
=
eval
(
expr
[
i
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
if
(
result
.
type
()
==
Node
::
boolean
&&
result
.
boolean_value
()
==
false
)
continue
;
if
(
result
.
type
()
==
Node
::
boolean
&&
result
.
boolean_value
()
==
false
)
continue
;
else
return
result
;
else
return
result
;
}
}
...
@@ -145,7 +147,7 @@ namespace Sass {
...
@@ -145,7 +147,7 @@ namespace Sass {
case
Node
:
:
conjunction
:
{
case
Node
:
:
conjunction
:
{
Node
result
;
Node
result
;
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
result
=
eval
(
expr
[
i
],
env
,
f_env
,
new_Node
,
ctx
);
result
=
eval
(
expr
[
i
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
if
(
result
.
type
()
==
Node
::
boolean
&&
result
.
boolean_value
()
==
false
)
return
result
;
if
(
result
.
type
()
==
Node
::
boolean
&&
result
.
boolean_value
()
==
false
)
return
result
;
}
}
return
result
;
return
result
;
...
@@ -153,9 +155,9 @@ namespace Sass {
...
@@ -153,9 +155,9 @@ namespace Sass {
case
Node
:
:
relation
:
{
case
Node
:
:
relation
:
{
Node
lhs
(
eval
(
expr
[
0
],
env
,
f_env
,
new_Node
,
ctx
));
Node
lhs
(
eval
(
expr
[
0
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
));
Node
op
(
expr
[
1
]);
Node
op
(
expr
[
1
]);
Node
rhs
(
eval
(
expr
[
2
],
env
,
f_env
,
new_Node
,
ctx
));
Node
rhs
(
eval
(
expr
[
2
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
));
Node
T
(
new_Node
(
Node
::
boolean
,
lhs
.
path
(),
lhs
.
line
(),
true
));
Node
T
(
new_Node
(
Node
::
boolean
,
lhs
.
path
(),
lhs
.
line
(),
true
));
Node
F
(
new_Node
(
Node
::
boolean
,
lhs
.
path
(),
lhs
.
line
(),
false
));
Node
F
(
new_Node
(
Node
::
boolean
,
lhs
.
path
(),
lhs
.
line
(),
false
));
...
@@ -175,11 +177,11 @@ namespace Sass {
...
@@ -175,11 +177,11 @@ namespace Sass {
case
Node
:
:
expression
:
{
case
Node
:
:
expression
:
{
Node
acc
(
new_Node
(
Node
::
expression
,
expr
.
path
(),
expr
.
line
(),
1
));
Node
acc
(
new_Node
(
Node
::
expression
,
expr
.
path
(),
expr
.
line
(),
1
));
acc
<<
eval
(
expr
[
0
],
env
,
f_env
,
new_Node
,
ctx
);
acc
<<
eval
(
expr
[
0
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
Node
rhs
(
eval
(
expr
[
2
],
env
,
f_env
,
new_Node
,
ctx
));
Node
rhs
(
eval
(
expr
[
2
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
));
accumulate
(
expr
[
1
].
type
(),
acc
,
rhs
,
new_Node
);
accumulate
(
expr
[
1
].
type
(),
acc
,
rhs
,
new_Node
);
for
(
size_t
i
=
3
,
S
=
expr
.
size
();
i
<
S
;
i
+=
2
)
{
for
(
size_t
i
=
3
,
S
=
expr
.
size
();
i
<
S
;
i
+=
2
)
{
Node
rhs
(
eval
(
expr
[
i
+
1
],
env
,
f_env
,
new_Node
,
ctx
));
Node
rhs
(
eval
(
expr
[
i
+
1
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
));
accumulate
(
expr
[
i
].
type
(),
acc
,
rhs
,
new_Node
);
accumulate
(
expr
[
i
].
type
(),
acc
,
rhs
,
new_Node
);
}
}
return
acc
.
size
()
==
1
?
acc
[
0
]
:
acc
;
return
acc
.
size
()
==
1
?
acc
[
0
]
:
acc
;
...
@@ -188,11 +190,11 @@ namespace Sass {
...
@@ -188,11 +190,11 @@ namespace Sass {
case
Node
:
:
term
:
{
case
Node
:
:
term
:
{
if
(
expr
.
should_eval
())
{
if
(
expr
.
should_eval
())
{
Node
acc
(
new_Node
(
Node
::
expression
,
expr
.
path
(),
expr
.
line
(),
1
));
Node
acc
(
new_Node
(
Node
::
expression
,
expr
.
path
(),
expr
.
line
(),
1
));
acc
<<
eval
(
expr
[
0
],
env
,
f_env
,
new_Node
,
ctx
);
acc
<<
eval
(
expr
[
0
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
Node
rhs
(
eval
(
expr
[
2
],
env
,
f_env
,
new_Node
,
ctx
));
Node
rhs
(
eval
(
expr
[
2
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
));
accumulate
(
expr
[
1
].
type
(),
acc
,
rhs
,
new_Node
);
accumulate
(
expr
[
1
].
type
(),
acc
,
rhs
,
new_Node
);
for
(
size_t
i
=
3
,
S
=
expr
.
size
();
i
<
S
;
i
+=
2
)
{
for
(
size_t
i
=
3
,
S
=
expr
.
size
();
i
<
S
;
i
+=
2
)
{
Node
rhs
(
eval
(
expr
[
i
+
1
],
env
,
f_env
,
new_Node
,
ctx
));
Node
rhs
(
eval
(
expr
[
i
+
1
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
));
accumulate
(
expr
[
i
].
type
(),
acc
,
rhs
,
new_Node
);
accumulate
(
expr
[
i
].
type
(),
acc
,
rhs
,
new_Node
);
}
}
return
acc
.
size
()
==
1
?
acc
[
0
]
:
acc
;
return
acc
.
size
()
==
1
?
acc
[
0
]
:
acc
;
...
@@ -243,11 +245,11 @@ namespace Sass {
...
@@ -243,11 +245,11 @@ namespace Sass {
// TO DO: default-constructed Function should be a generic callback (maybe)
// TO DO: default-constructed Function should be a generic callback (maybe)
pair
<
string
,
size_t
>
sig
(
expr
[
0
].
token
().
to_string
(),
expr
[
1
].
size
());
pair
<
string
,
size_t
>
sig
(
expr
[
0
].
token
().
to_string
(),
expr
[
1
].
size
());
if
(
!
f_env
.
count
(
sig
))
return
expr
;
if
(
!
f_env
.
count
(
sig
))
return
expr
;
return
apply_function
(
f_env
[
sig
],
expr
[
1
],
env
,
f_env
,
new_Node
,
ctx
);
return
apply_function
(
f_env
[
sig
],
expr
[
1
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
break
;
}
break
;
case
Node
:
:
unary_plus
:
{
case
Node
:
:
unary_plus
:
{
Node
arg
(
eval
(
expr
[
0
],
env
,
f_env
,
new_Node
,
ctx
));
Node
arg
(
eval
(
expr
[
0
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
));
if
(
arg
.
is_numeric
())
{
if
(
arg
.
is_numeric
())
{
return
arg
;
return
arg
;
}
}
...
@@ -258,7 +260,7 @@ namespace Sass {
...
@@ -258,7 +260,7 @@ namespace Sass {
}
break
;
}
break
;
case
Node
:
:
unary_minus
:
{
case
Node
:
:
unary_minus
:
{
Node
arg
(
eval
(
expr
[
0
],
env
,
f_env
,
new_Node
,
ctx
));
Node
arg
(
eval
(
expr
[
0
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
));
if
(
arg
.
is_numeric
())
{
if
(
arg
.
is_numeric
())
{
return
new_Node
(
expr
.
path
(),
expr
.
line
(),
-
arg
.
numeric_value
());
return
new_Node
(
expr
.
path
(),
expr
.
line
(),
-
arg
.
numeric_value
());
}
}
...
@@ -271,13 +273,13 @@ namespace Sass {
...
@@ -271,13 +273,13 @@ namespace Sass {
case
Node
:
:
string_schema
:
case
Node
:
:
string_schema
:
case
Node
:
:
value_schema
:
{
case
Node
:
:
value_schema
:
{
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
expr
[
i
]
=
eval
(
expr
[
i
],
env
,
f_env
,
new_Node
,
ctx
);
expr
[
i
]
=
eval
(
expr
[
i
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
return
expr
;
return
expr
;
}
break
;
}
break
;
case
Node
:
:
css_import
:
{
case
Node
:
:
css_import
:
{
expr
[
0
]
=
eval
(
expr
[
0
],
env
,
f_env
,
new_Node
,
ctx
);
expr
[
0
]
=
eval
(
expr
[
0
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
return
expr
;
return
expr
;
}
break
;
}
break
;
...
@@ -381,7 +383,7 @@ namespace Sass {
...
@@ -381,7 +383,7 @@ namespace Sass {
}
}
}
}
Node
apply_mixin
(
Node
mixin
,
const
Node
args
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
ctx
)
Node
apply_mixin
(
Node
mixin
,
const
Node
args
,
Node
prefix
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
ctx
)
{
{
Node
params
(
mixin
[
1
]);
Node
params
(
mixin
[
1
]);
Node
body
(
new_Node
(
mixin
[
2
]));
// clone the body
Node
body
(
new_Node
(
mixin
[
2
]));
// clone the body
...
@@ -403,7 +405,7 @@ namespace Sass {
...
@@ -403,7 +405,7 @@ namespace Sass {
}
}
if
(
!
valid_param
)
throw_eval_error
(
"mixin "
+
mixin
[
0
].
to_string
(
""
)
+
" has no parameter named "
+
name
.
to_string
(),
arg
.
path
(),
arg
.
line
());
if
(
!
valid_param
)
throw_eval_error
(
"mixin "
+
mixin
[
0
].
to_string
(
""
)
+
" has no parameter named "
+
name
.
to_string
(),
arg
.
path
(),
arg
.
line
());
if
(
!
bindings
.
query
(
name
))
{
if
(
!
bindings
.
query
(
name
))
{
bindings
[
name
]
=
eval
(
arg
[
1
],
env
,
f_env
,
new_Node
,
ctx
);
bindings
[
name
]
=
eval
(
arg
[
1
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
}
}
else
{
else
{
...
@@ -415,7 +417,7 @@ namespace Sass {
...
@@ -415,7 +417,7 @@ namespace Sass {
}
}
Node
param
(
params
[
j
]);
Node
param
(
params
[
j
]);
Token
name
(
param
.
type
()
==
Node
::
variable
?
param
.
token
()
:
param
[
0
].
token
());
Token
name
(
param
.
type
()
==
Node
::
variable
?
param
.
token
()
:
param
[
0
].
token
());
bindings
[
name
]
=
eval
(
args
[
i
],
env
,
f_env
,
new_Node
,
ctx
);
bindings
[
name
]
=
eval
(
args
[
i
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
++
j
;
++
j
;
}
}
}
}
...
@@ -425,19 +427,19 @@ namespace Sass {
...
@@ -425,19 +427,19 @@ namespace Sass {
Node
param
(
params
[
i
]);
Node
param
(
params
[
i
]);
Token
name
(
param
[
0
].
token
());
Token
name
(
param
[
0
].
token
());
if
(
!
bindings
.
query
(
name
))
{
if
(
!
bindings
.
query
(
name
))
{
bindings
[
name
]
=
eval
(
param
[
1
],
env
,
f_env
,
new_Node
,
ctx
);
bindings
[
name
]
=
eval
(
param
[
1
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
}
}
}
}
// lexically link the new environment and eval the mixin's body
// lexically link the new environment and eval the mixin's body
bindings
.
link
(
env
.
global
?
*
env
.
global
:
env
);
bindings
.
link
(
env
.
global
?
*
env
.
global
:
env
);
for
(
size_t
i
=
0
,
S
=
body
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
i
=
0
,
S
=
body
.
size
();
i
<
S
;
++
i
)
{
body
[
i
]
=
eval
(
body
[
i
],
bindings
,
f_env
,
new_Node
,
ctx
);
body
[
i
]
=
eval
(
body
[
i
],
prefix
,
bindings
,
f_env
,
new_Node
,
ctx
);
}
}
return
body
;
return
body
;
}
}
Node
apply_function
(
const
Function
&
f
,
const
Node
args
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
ctx
)
Node
apply_function
(
const
Function
&
f
,
const
Node
args
,
Node
prefix
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
ctx
)
{
{
map
<
Token
,
Node
>
bindings
;
map
<
Token
,
Node
>
bindings
;
// bind arguments
// bind arguments
...
@@ -445,15 +447,122 @@ namespace Sass {
...
@@ -445,15 +447,122 @@ namespace Sass {
if
(
args
[
i
].
type
()
==
Node
::
assignment
)
{
if
(
args
[
i
].
type
()
==
Node
::
assignment
)
{
Node
arg
(
args
[
i
]);
Node
arg
(
args
[
i
]);
Token
name
(
arg
[
0
].
token
());
Token
name
(
arg
[
0
].
token
());
bindings
[
name
]
=
eval
(
arg
[
1
],
env
,
f_env
,
new_Node
,
ctx
);
bindings
[
name
]
=
eval
(
arg
[
1
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
else
{
else
{
// TO DO: ensure (j < f.parameters.size())
// TO DO: ensure (j < f.parameters.size())
bindings
[
f
.
parameters
[
j
]]
=
eval
(
args
[
i
],
env
,
f_env
,
new_Node
,
ctx
);
bindings
[
f
.
parameters
[
j
]]
=
eval
(
args
[
i
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
++
j
;
++
j
;
}
}
}
}
return
f
(
bindings
,
new_Node
);
return
f
(
bindings
,
new_Node
);
}
}
Node
expand_selector
(
Node
sel
,
Node
pre
,
Node_Factory
&
new_Node
)
{
if
(
pre
.
type
()
==
Node
::
none
)
return
sel
;
if
(
sel
.
has_backref
())
{
if
((
pre
.
type
()
==
Node
::
selector_group
)
&&
(
sel
.
type
()
==
Node
::
selector_group
))
{
Node
group
(
new_Node
(
Node
::
selector_group
,
sel
.
path
(),
sel
.
line
(),
pre
.
size
()
*
sel
.
size
()));
for
(
size_t
i
=
0
,
S
=
pre
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
j
=
0
,
T
=
sel
.
size
();
j
<
T
;
++
j
)
{
group
<<
expand_backref
(
new_Node
(
sel
[
j
]),
pre
[
i
]);
}
}
return
group
;
}
else
if
((
pre
.
type
()
==
Node
::
selector_group
)
&&
(
sel
.
type
()
!=
Node
::
selector_group
))
{
Node
group
(
new_Node
(
Node
::
selector_group
,
sel
.
path
(),
sel
.
line
(),
pre
.
size
()));
for
(
size_t
i
=
0
,
S
=
pre
.
size
();
i
<
S
;
++
i
)
{
group
<<
expand_backref
(
new_Node
(
sel
),
pre
[
i
]);
}
return
group
;
}
else
if
((
pre
.
type
()
!=
Node
::
selector_group
)
&&
(
sel
.
type
()
==
Node
::
selector_group
))
{
Node
group
(
new_Node
(
Node
::
selector_group
,
sel
.
path
(),
sel
.
line
(),
sel
.
size
()));
for
(
size_t
i
=
0
,
S
=
sel
.
size
();
i
<
S
;
++
i
)
{
group
<<
expand_backref
(
new_Node
(
sel
[
i
]),
pre
);
}
return
group
;
}
else
{
return
expand_backref
(
new_Node
(
sel
),
pre
);
}
}
if
((
pre
.
type
()
==
Node
::
selector_group
)
&&
(
sel
.
type
()
==
Node
::
selector_group
))
{
Node
group
(
new_Node
(
Node
::
selector_group
,
sel
.
path
(),
sel
.
line
(),
pre
.
size
()
*
sel
.
size
()));
for
(
size_t
i
=
0
,
S
=
pre
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
j
=
0
,
T
=
sel
.
size
();
j
<
T
;
++
j
)
{
Node
new_sel
(
new_Node
(
Node
::
selector
,
sel
.
path
(),
sel
.
line
(),
2
));
if
(
pre
[
i
].
type
()
==
Node
::
selector
)
new_sel
+=
pre
;
else
new_sel
<<
pre
;
if
(
sel
[
j
].
type
()
==
Node
::
selector
)
new_sel
+=
sel
[
j
];
else
new_sel
<<
sel
[
j
];
group
<<
new_sel
;
}
}
return
group
;
}
else
if
((
pre
.
type
()
==
Node
::
selector_group
)
&&
(
sel
.
type
()
!=
Node
::
selector_group
))
{
Node
group
(
new_Node
(
Node
::
selector_group
,
sel
.
path
(),
sel
.
line
(),
pre
.
size
()));
for
(
size_t
i
=
0
,
S
=
pre
.
size
();
i
<
S
;
++
i
)
{
Node
new_sel
(
new_Node
(
Node
::
selector
,
sel
.
path
(),
sel
.
line
(),
2
));
if
(
pre
[
i
].
type
()
==
Node
::
selector
)
new_sel
+=
pre
;
else
new_sel
<<
pre
;
if
(
sel
.
type
()
==
Node
::
selector
)
new_sel
+=
sel
;
else
new_sel
<<
sel
;
group
<<
new_sel
;
}
return
group
;
}
else
if
((
pre
.
type
()
!=
Node
::
selector_group
)
&&
(
sel
.
type
()
==
Node
::
selector_group
))
{
Node
group
(
new_Node
(
Node
::
selector_group
,
sel
.
path
(),
sel
.
line
(),
sel
.
size
()));
for
(
size_t
i
=
0
,
S
=
sel
.
size
();
i
<
S
;
++
i
)
{
Node
new_sel
(
new_Node
(
Node
::
selector
,
sel
.
path
(),
sel
.
line
(),
2
));
if
(
pre
.
type
()
==
Node
::
selector
)
new_sel
+=
pre
;
else
new_sel
<<
pre
;
if
(
sel
[
i
].
type
()
==
Node
::
selector
)
new_sel
+=
sel
[
i
];
else
new_sel
<<
sel
[
i
];
group
<<
new_sel
;
}
return
group
;
}
else
{
Node
new_sel
(
new_Node
(
Node
::
selector
,
sel
.
path
(),
sel
.
line
(),
2
));
if
(
pre
.
type
()
==
Node
::
selector
)
new_sel
+=
pre
;
else
new_sel
<<
pre
;
if
(
sel
.
type
()
==
Node
::
selector
)
new_sel
+=
sel
;
else
new_sel
<<
sel
;
return
new_sel
;
}
// unreachable statement
return
Node
();
}
Node
expand_backref
(
Node
sel
,
Node
pre
)
{
switch
(
sel
.
type
())
{
case
Node
:
:
backref
:
{
return
pre
;
}
break
;
case
Node
:
:
simple_selector_sequence
:
case
Node
:
:
selector
:
{
for
(
size_t
i
=
0
,
S
=
sel
.
size
();
i
<
S
;
++
i
)
{
sel
[
i
]
=
expand_backref
(
sel
[
i
],
pre
);
}
return
sel
;
}
break
;
default:
{
return
sel
;
}
break
;
}
// unreachable statement
return
Node
();
}
}
}
eval_apply.hpp
View file @
bbd04d5e
...
@@ -11,10 +11,12 @@
...
@@ -11,10 +11,12 @@
namespace
Sass
{
namespace
Sass
{
using
std
::
map
;
using
std
::
map
;
Node
eval
(
Node
expr
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
src_refs
);
Node
eval
(
Node
expr
,
Node
prefix
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
src_refs
);
Node
accumulate
(
Node
::
Type
op
,
Node
acc
,
Node
rhs
,
Node_Factory
&
new_Node
);
Node
accumulate
(
Node
::
Type
op
,
Node
acc
,
Node
rhs
,
Node_Factory
&
new_Node
);
double
operate
(
Node
::
Type
op
,
double
lhs
,
double
rhs
);
double
operate
(
Node
::
Type
op
,
double
lhs
,
double
rhs
);
Node
apply_mixin
(
Node
mixin
,
const
Node
args
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
src_refs
);
Node
apply_mixin
(
Node
mixin
,
const
Node
args
,
Node
prefix
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
src_refs
);
Node
apply_function
(
const
Function
&
f
,
const
Node
args
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
src_refs
);
Node
apply_function
(
const
Function
&
f
,
const
Node
args
,
Node
prefix
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
src_refs
);
Node
expand_selector
(
Node
sel
,
Node
pre
,
Node_Factory
&
new_Node
);
Node
expand_backref
(
Node
sel
,
Node
pre
);
}
}
\ No newline at end of file
sass_interface.cpp
View file @
bbd04d5e
...
@@ -39,7 +39,12 @@ extern "C" {
...
@@ -39,7 +39,12 @@ extern "C" {
{
{
using
namespace
Sass
;
using
namespace
Sass
;
doc
.
parse_scss
();
doc
.
parse_scss
();
eval
(
doc
.
root
,
doc
.
context
.
global_env
,
doc
.
context
.
function_env
,
doc
.
context
.
new_Node
,
doc
.
context
);
eval
(
doc
.
root
,
doc
.
context
.
new_Node
(
Node
::
none
,
doc
.
path
,
doc
.
line
,
0
),
doc
.
context
.
global_env
,
doc
.
context
.
function_env
,
doc
.
context
.
new_Node
,
doc
.
context
);
string
output
(
doc
.
emit_css
(
static_cast
<
Document
::
CSS_Style
>
(
style
)));
string
output
(
doc
.
emit_css
(
static_cast
<
Document
::
CSS_Style
>
(
style
)));
char
*
c_output
=
(
char
*
)
malloc
(
output
.
size
()
+
1
);
char
*
c_output
=
(
char
*
)
malloc
(
output
.
size
()
+
1
);
strcpy
(
c_output
,
output
.
c_str
());
strcpy
(
c_output
,
output
.
c_str
());
...
...
test_node_factory.cpp
View file @
bbd04d5e
#include <iostream>
#include <iostream>
#include <string>
#include <tr1/unordered_map>
#include <map>
#ifndef SASS_NODE_INCLUDED
#ifndef SASS_NODE_INCLUDED
#include "node.hpp"
#include "node.hpp"
...
@@ -60,9 +63,21 @@ int main()
...
@@ -60,9 +63,21 @@ int main()
cout
<<
block2
[
1
][
3
].
numeric_value
()
<<
endl
;
cout
<<
block2
[
1
][
3
].
numeric_value
()
<<
endl
;
block2
[
1
][
3
]
=
new_Node
(
""
,
0
,
.9876
);
block2
[
1
][
3
]
=
new_Node
(
""
,
0
,
.9876
);
cout
<<
block1
[
1
][
3
].
numeric_value
()
<<
endl
;
cout
<<
block1
[
1
][
3
].
numeric_value
()
<<
endl
;
cout
<<
block2
[
1
][
3
].
numeric_value
()
<<
endl
;
cout
<<
block2
[
1
][
3
].
numeric_value
()
<<
endl
<<
endl
;
map
<
Node
,
string
>
dict
;
Node
n
(
new_Node
(
""
,
0
,
42
));
Node
m
(
new_Node
(
""
,
0
,
41
));
dict
[
n
]
=
"hello"
;
dict
[
m
]
=
"goodbye"
;
cout
<<
dict
[
m
]
<<
" "
<<
dict
[
n
]
<<
endl
;
new_Node
.
free
();
new_Node
.
free
();
return
0
;
return
0
;
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment