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
e6ced9b7
Commit
e6ced9b7
authored
Jun 01, 2012
by
Aaron Leung
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Working on pure-Sass function evaluator. Needs a different evaluation algorithm.
parent
94de55d7
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
136 additions
and
6 deletions
+136
-6
document_parser.cpp
document_parser.cpp
+6
-0
eval_apply.cpp
eval_apply.cpp
+122
-0
eval_apply.hpp
eval_apply.hpp
+4
-3
node.hpp
node.hpp
+2
-0
prelexer.cpp
prelexer.cpp
+1
-1
prelexer.hpp
prelexer.hpp
+1
-2
No files found.
document_parser.cpp
View file @
e6ced9b7
...
@@ -504,6 +504,12 @@ namespace Sass {
...
@@ -504,6 +504,12 @@ namespace Sass {
else
if
(
peek
<
while_directive
>
())
{
else
if
(
peek
<
while_directive
>
())
{
block
<<
parse_while_directive
(
surrounding_ruleset
,
inside_of
);
block
<<
parse_while_directive
(
surrounding_ruleset
,
inside_of
);
}
}
else
if
(
lex
<
return_directive
>
())
{
Node
ret_expr
(
context
.
new_Node
(
Node
::
return_directive
,
path
,
line
,
1
));
ret_expr
<<
parse_list
();
block
<<
ret_expr
;
semicolon
=
true
;
}
else
if
(
inside_of
==
Node
::
function
)
{
else
if
(
inside_of
==
Node
::
function
)
{
throw_syntax_error
(
"only variable declarations and control directives are allowed inside functions"
);
throw_syntax_error
(
"only variable declarations and control directives are allowed inside functions"
);
}
}
...
...
eval_apply.cpp
View file @
e6ced9b7
...
@@ -124,6 +124,8 @@ namespace Sass {
...
@@ -124,6 +124,8 @@ namespace Sass {
val
=
eval
(
val
,
prefix
,
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 a binding exists (possible upframe), then update it.
// Otherwise, make a new on in the current frame.
if
(
env
.
query
(
var
.
token
()))
{
if
(
env
.
query
(
var
.
token
()))
{
env
[
var
.
token
()]
=
val
;
env
[
var
.
token
()]
=
val
;
}
}
...
@@ -496,6 +498,7 @@ namespace Sass {
...
@@ -496,6 +498,7 @@ namespace Sass {
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
Environment
bindings
;
Environment
bindings
;
// TO DO: REFACTOR THE ARG-BINDER
// bind arguments
// bind arguments
for
(
size_t
i
=
0
,
j
=
0
,
S
=
args
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
i
=
0
,
j
=
0
,
S
=
args
.
size
();
i
<
S
;
++
i
)
{
if
(
args
[
i
].
type
()
==
Node
::
assignment
)
{
if
(
args
[
i
].
type
()
==
Node
::
assignment
)
{
...
@@ -539,11 +542,14 @@ namespace Sass {
...
@@ -539,11 +542,14 @@ namespace Sass {
}
}
}
}
}
}
// END ARG-BINDER
// link the new environment and eval the mixin's body
// link the new environment and eval the mixin's body
if
(
dynamic_scope
)
{
if
(
dynamic_scope
)
{
bindings
.
link
(
env
);
bindings
.
link
(
env
);
}
}
else
{
else
{
// C-style scope for now (current/global, nothing in between). May need
// to implement full lexical scope someday.
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
)
{
...
@@ -557,6 +563,7 @@ namespace Sass {
...
@@ -557,6 +563,7 @@ namespace Sass {
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
)
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
)
{
{
if
(
f
.
primitive
)
{
map
<
Token
,
Node
>
bindings
;
map
<
Token
,
Node
>
bindings
;
// bind arguments
// bind arguments
for
(
size_t
i
=
0
,
j
=
0
,
S
=
args
.
size
();
i
<
S
;
++
i
)
{
for
(
size_t
i
=
0
,
j
=
0
,
S
=
args
.
size
();
i
<
S
;
++
i
)
{
...
@@ -573,6 +580,121 @@ namespace Sass {
...
@@ -573,6 +580,121 @@ namespace Sass {
}
}
return
f
(
bindings
,
new_Node
);
return
f
(
bindings
,
new_Node
);
}
}
else
{
cerr
<<
"applying pure-Sass function"
<<
endl
;
Node
params
(
f
.
definition
[
1
]);
Node
body
(
new_Node
(
f
.
definition
[
2
]));
Environment
bindings
;
// TO DO: REFACTOR THE ARG-BINDER
// bind arguments
for
(
size_t
i
=
0
,
j
=
0
,
S
=
args
.
size
();
i
<
S
;
++
i
)
{
if
(
args
[
i
].
type
()
==
Node
::
assignment
)
{
Node
arg
(
args
[
i
]);
Token
name
(
arg
[
0
].
token
());
// check that the keyword arg actually names a formal parameter
bool
valid_param
=
false
;
for
(
size_t
k
=
0
,
S
=
params
.
size
();
k
<
S
;
++
k
)
{
Node
param_k
=
params
[
k
];
if
(
param_k
.
type
()
==
Node
::
assignment
)
param_k
=
param_k
[
0
];
if
(
arg
[
0
]
==
param_k
)
{
valid_param
=
true
;
break
;
}
}
if
(
!
valid_param
)
throw_eval_error
(
"mixin "
+
f
.
name
+
" has no parameter named "
+
name
.
to_string
(),
arg
.
path
(),
arg
.
line
());
if
(
!
bindings
.
query
(
name
))
{
bindings
[
name
]
=
eval
(
arg
[
1
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
else
{
// ensure that the number of ordinal args < params.size()
if
(
j
>=
params
.
size
())
{
stringstream
ss
;
ss
<<
"mixin "
<<
f
.
name
<<
" only takes "
<<
params
.
size
()
<<
((
params
.
size
()
==
1
)
?
" argument"
:
" arguments"
);
throw_eval_error
(
ss
.
str
(),
args
[
i
].
path
(),
args
[
i
].
line
());
}
Node
param
(
params
[
j
]);
Token
name
(
param
.
type
()
==
Node
::
variable
?
param
.
token
()
:
param
[
0
].
token
());
bindings
[
name
]
=
eval
(
args
[
i
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
++
j
;
}
}
// plug the holes with default arguments if any
for
(
size_t
i
=
0
,
S
=
params
.
size
();
i
<
S
;
++
i
)
{
if
(
params
[
i
].
type
()
==
Node
::
assignment
)
{
Node
param
(
params
[
i
]);
Token
name
(
param
[
0
].
token
());
if
(
!
bindings
.
query
(
name
))
{
bindings
[
name
]
=
eval
(
param
[
1
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
}
}
}
// END ARG-BINDER
bindings
.
link
(
env
.
global
?
*
env
.
global
:
env
);
return
function_eval
(
body
,
bindings
,
new_Node
,
ctx
);
}
}
// Special function for evaluating pure Sass functions. The evaluation
// algorithm is different in this case because the body needs to be
// executed and a single value needs to be returned directly, rather than
// styles being expanded and spliced in place.
Node
function_eval
(
Node
body
,
Environment
&
bindings
,
Node_Factory
&
new_Node
,
Context
&
ctx
)
{
for
(
size_t
i
=
0
,
S
=
body
.
size
();
i
<
S
;
++
i
)
{
Node
stm
(
body
[
i
]);
switch
(
stm
.
type
())
{
case
Node
:
:
assignment
:
{
Node
val
(
stm
[
1
]);
if
(
val
.
type
()
==
Node
::
comma_list
||
val
.
type
()
==
Node
::
space_list
)
{
for
(
size_t
i
=
0
,
S
=
val
.
size
();
i
<
S
;
++
i
)
{
if
(
val
[
i
].
should_eval
())
val
[
i
]
=
eval
(
val
[
i
],
Node
(),
bindings
,
ctx
.
function_env
,
new_Node
,
ctx
);
}
}
else
{
val
=
eval
(
val
,
Node
(),
bindings
,
ctx
.
function_env
,
new_Node
,
ctx
);
}
Node
var
(
stm
[
0
]);
// If a binding exists (possible upframe), then update it.
// Otherwise, make a new on in the current frame.
if
(
bindings
.
query
(
var
.
token
()))
{
bindings
[
var
.
token
()]
=
val
;
}
else
{
bindings
.
current_frame
[
var
.
token
()]
=
val
;
}
}
break
;
case
Node
:
:
if_directive
:
{
}
break
;
case
Node
:
:
for_through_directive
:
case
Node
:
:
for_to_directive
:
{
}
break
;
case
Node
:
:
each_directive
:
{
}
break
;
case
Node
:
:
while_directive
:
{
}
break
;
case
Node
:
:
return_directive
:
{
}
break
;
default:
{
}
break
;
}
}
return
new_Node
(
Node
::
none
,
""
,
0
,
0
);
}
// Expand a selector with respect to its prefix/context. Two separate cases:
// Expand a selector with respect to its prefix/context. Two separate cases:
// when the selector has backrefs, substitute the prefix for each occurrence
// when the selector has backrefs, substitute the prefix for each occurrence
...
...
eval_apply.hpp
View file @
e6ced9b7
...
@@ -11,12 +11,13 @@
...
@@ -11,12 +11,13 @@
namespace
Sass
{
namespace
Sass
{
using
std
::
map
;
using
std
::
map
;
Node
eval
(
Node
expr
,
Node
prefix
,
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
&
ctx
);
Node
function_eval
(
Node
stm
,
Environment
&
bindings
,
Node_Factory
&
new_Node
,
Context
&
ctx
);
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
,
Node
prefix
,
Environment
&
env
,
map
<
pair
<
string
,
size_t
>
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
src_refs
,
bool
dynamic_scope
=
false
);
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
,
bool
dynamic_scope
=
false
);
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
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
);
Node
expand_selector
(
Node
sel
,
Node
pre
,
Node_Factory
&
new_Node
);
Node
expand_selector
(
Node
sel
,
Node
pre
,
Node_Factory
&
new_Node
);
Node
expand_backref
(
Node
sel
,
Node
pre
);
Node
expand_backref
(
Node
sel
,
Node
pre
);
void
extend_selectors
(
vector
<
pair
<
Node
,
Node
>
>&
,
Node_Factory
&
);
void
extend_selectors
(
vector
<
pair
<
Node
,
Node
>
>&
,
Node_Factory
&
);
...
...
node.hpp
View file @
e6ced9b7
...
@@ -153,6 +153,8 @@ namespace Sass {
...
@@ -153,6 +153,8 @@ namespace Sass {
for_to_directive
,
for_to_directive
,
each_directive
,
each_directive
,
while_directive
,
while_directive
,
return_directive
,
content_directive
,
variable
,
variable
,
assignment
assignment
...
...
prelexer.cpp
View file @
e6ced9b7
...
@@ -112,7 +112,7 @@ namespace Sass {
...
@@ -112,7 +112,7 @@ namespace Sass {
return
exactly
<
function_kwd
>
(
src
);
return
exactly
<
function_kwd
>
(
src
);
}
}
extern
const
char
return_kwd
[]
=
"@return"
;
extern
const
char
return_kwd
[]
=
"@return"
;
const
char
*
ret
(
const
char
*
src
)
{
const
char
*
ret
urn_directive
(
const
char
*
src
)
{
return
exactly
<
return_kwd
>
(
src
);
return
exactly
<
return_kwd
>
(
src
);
}
}
extern
const
char
include_kwd
[]
=
"@include"
;
extern
const
char
include_kwd
[]
=
"@include"
;
...
...
prelexer.hpp
View file @
e6ced9b7
...
@@ -310,7 +310,7 @@ namespace Sass {
...
@@ -310,7 +310,7 @@ namespace Sass {
const
char
*
import
(
const
char
*
src
);
const
char
*
import
(
const
char
*
src
);
const
char
*
mixin
(
const
char
*
src
);
const
char
*
mixin
(
const
char
*
src
);
const
char
*
function
(
const
char
*
src
);
const
char
*
function
(
const
char
*
src
);
const
char
*
ret
(
const
char
*
src
);
const
char
*
ret
urn_directive
(
const
char
*
src
);
const
char
*
include
(
const
char
*
src
);
const
char
*
include
(
const
char
*
src
);
const
char
*
extend
(
const
char
*
src
);
const
char
*
extend
(
const
char
*
src
);
...
@@ -409,7 +409,6 @@ namespace Sass {
...
@@ -409,7 +409,6 @@ namespace Sass {
if
(
mx
(
beg
))
return
beg
;
if
(
mx
(
beg
))
return
beg
;
++
beg
;
++
beg
;
}
}
return
0
;
return
0
;
}
}
template
<
char
c
>
template
<
char
c
>
...
...
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