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
b7df7897
Commit
b7df7897
authored
Apr 03, 2012
by
Aaron Leung
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
General framework for built-in Sass functions.
parent
c60e12c2
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
106 additions
and
45 deletions
+106
-45
context.hpp
context.hpp
+3
-0
eval_apply.cpp
eval_apply.cpp
+55
-38
eval_apply.hpp
eval_apply.hpp
+4
-2
functions.cpp
functions.cpp
+12
-0
functions.hpp
functions.hpp
+25
-0
sassc.cpp
sassc.cpp
+7
-5
No files found.
context.hpp
View file @
b7df7897
#define SASS_CONTEXT_INCLUDED
#define SASS_CONTEXT_INCLUDED
#include "functions.hpp"
namespace
Sass
{
namespace
Sass
{
using
std
::
map
;
using
std
::
map
;
...
@@ -35,6 +37,7 @@ namespace Sass {
...
@@ -35,6 +37,7 @@ namespace Sass {
struct
Context
{
struct
Context
{
Environment
global_env
;
Environment
global_env
;
map
<
string
,
Function
>
function_env
;
vector
<
char
*>
source_refs
;
vector
<
char
*>
source_refs
;
size_t
ref_count
;
size_t
ref_count
;
...
...
eval_apply.cpp
View file @
b7df7897
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
namespace
Sass
{
namespace
Sass
{
using
std
::
cerr
;
using
std
::
endl
;
using
std
::
cerr
;
using
std
::
endl
;
Node
eval
(
Node
&
expr
,
Environment
&
env
)
Node
eval
(
Node
&
expr
,
Environment
&
env
,
map
<
string
,
Function
>&
f_env
)
{
{
switch
(
expr
.
type
)
switch
(
expr
.
type
)
{
{
...
@@ -16,28 +16,23 @@ namespace Sass {
...
@@ -16,28 +16,23 @@ namespace Sass {
case
Node
:
:
expansion
:
{
case
Node
:
:
expansion
:
{
Token
name
(
expr
[
0
].
content
.
token
);
Token
name
(
expr
[
0
].
content
.
token
);
// cerr << "EVALUATING EXPANSION: " << string(name) << endl;
Node
args
(
expr
[
1
]);
Node
args
(
expr
[
1
]);
Node
mixin
(
env
[
name
]);
Node
mixin
(
env
[
name
]);
Node
expansion
(
apply
(
mixin
,
args
,
env
));
Node
expansion
(
apply
_mixin
(
mixin
,
args
,
env
,
f_
env
));
expr
.
content
.
children
->
pop_back
();
expr
.
content
.
children
->
pop_back
();
expr
.
content
.
children
->
pop_back
();
expr
.
content
.
children
->
pop_back
();
expr
+=
expansion
;
expr
+=
expansion
;
// expr[0].has_rules_or_comments |= expansion[0].has_rules_or_comments;
// expr[0].has_rulesets |= expansion[0].has_rulesets;
// expr[0].has_propsets |= expansion[0].has_propsets;
// expr[0].has_expansions |= expansion[0].has_expansions;
return
expr
;
return
expr
;
}
break
;
}
break
;
case
Node
:
:
ruleset
:
{
case
Node
:
:
ruleset
:
{
eval
(
expr
[
1
],
env
);
eval
(
expr
[
1
],
env
,
f_env
);
return
expr
;
return
expr
;
}
break
;
}
break
;
case
Node
:
:
root
:
{
case
Node
:
:
root
:
{
for
(
int
i
=
0
;
i
<
expr
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
expr
.
size
();
++
i
)
{
eval
(
expr
[
i
],
env
);
eval
(
expr
[
i
],
env
,
f_env
);
}
}
return
expr
;
return
expr
;
}
break
;
}
break
;
...
@@ -46,7 +41,7 @@ namespace Sass {
...
@@ -46,7 +41,7 @@ namespace Sass {
Environment
current
;
Environment
current
;
current
.
link
(
env
);
current
.
link
(
env
);
for
(
int
i
=
0
;
i
<
expr
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
expr
.
size
();
++
i
)
{
eval
(
expr
[
i
],
current
);
eval
(
expr
[
i
],
current
,
f_env
);
}
}
return
expr
;
return
expr
;
}
break
;
}
break
;
...
@@ -55,11 +50,11 @@ namespace Sass {
...
@@ -55,11 +50,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
(
int
i
=
0
;
i
<
val
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
val
.
size
();
++
i
)
{
if
(
val
[
i
].
eval_me
)
val
[
i
]
=
eval
(
val
[
i
],
env
);
if
(
val
[
i
].
eval_me
)
val
[
i
]
=
eval
(
val
[
i
],
env
,
f_env
);
}
}
}
}
else
{
else
{
val
=
eval
(
val
,
env
);
val
=
eval
(
val
,
env
,
f_env
);
}
}
Node
var
(
expr
[
0
]);
Node
var
(
expr
[
0
]);
if
(
env
.
query
(
var
.
content
.
token
))
{
if
(
env
.
query
(
var
.
content
.
token
))
{
...
@@ -75,31 +70,28 @@ namespace Sass {
...
@@ -75,31 +70,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
(
int
i
=
0
;
i
<
rhs
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
rhs
.
size
();
++
i
)
{
if
(
rhs
[
i
].
eval_me
)
rhs
[
i
]
=
eval
(
rhs
[
i
],
env
);
if
(
rhs
[
i
].
eval_me
)
rhs
[
i
]
=
eval
(
rhs
[
i
],
env
,
f_env
);
}
}
}
}
else
{
else
{
if
(
rhs
.
eval_me
)
expr
[
1
]
=
eval
(
rhs
,
env
);
if
(
rhs
.
eval_me
)
expr
[
1
]
=
eval
(
rhs
,
env
,
f_env
);
}
}
return
expr
;
return
expr
;
}
break
;
}
break
;
case
Node
:
:
comma_list
:
case
Node
:
:
comma_list
:
case
Node
:
:
space_list
:
{
case
Node
:
:
space_list
:
{
if
(
expr
.
eval_me
)
{
if
(
expr
.
eval_me
)
expr
[
0
]
=
eval
(
expr
[
0
],
env
,
f_env
);
// *(expr.children->begin()) = eval(expr[0], env);
expr
[
0
]
=
eval
(
expr
[
0
],
env
);
}
return
expr
;
return
expr
;
}
break
;
}
break
;
case
Node
:
:
expression
:
{
case
Node
:
:
expression
:
{
Node
acc
(
Node
::
expression
,
expr
.
line_number
,
1
);
Node
acc
(
Node
::
expression
,
expr
.
line_number
,
1
);
acc
<<
eval
(
expr
[
0
],
env
);
acc
<<
eval
(
expr
[
0
],
env
,
f_env
);
Node
rhs
(
eval
(
expr
[
2
],
env
));
Node
rhs
(
eval
(
expr
[
2
],
env
,
f_env
));
accumulate
(
expr
[
1
].
type
,
acc
,
rhs
);
accumulate
(
expr
[
1
].
type
,
acc
,
rhs
);
for
(
int
i
=
3
;
i
<
expr
.
size
();
i
+=
2
)
{
for
(
int
i
=
3
;
i
<
expr
.
size
();
i
+=
2
)
{
Node
rhs
(
eval
(
expr
[
i
+
1
],
env
));
Node
rhs
(
eval
(
expr
[
i
+
1
],
env
,
f_env
));
accumulate
(
expr
[
i
].
type
,
acc
,
rhs
);
accumulate
(
expr
[
i
].
type
,
acc
,
rhs
);
}
}
return
acc
.
size
()
==
1
?
acc
[
0
]
:
acc
;
return
acc
.
size
()
==
1
?
acc
[
0
]
:
acc
;
...
@@ -108,11 +100,11 @@ namespace Sass {
...
@@ -108,11 +100,11 @@ namespace Sass {
case
Node
:
:
term
:
{
case
Node
:
:
term
:
{
if
(
expr
.
eval_me
)
{
if
(
expr
.
eval_me
)
{
Node
acc
(
Node
::
expression
,
expr
.
line_number
,
1
);
Node
acc
(
Node
::
expression
,
expr
.
line_number
,
1
);
acc
<<
eval
(
expr
[
0
],
env
);
acc
<<
eval
(
expr
[
0
],
env
,
f_env
);
Node
rhs
(
eval
(
expr
[
2
],
env
));
Node
rhs
(
eval
(
expr
[
2
],
env
,
f_env
));
accumulate
(
expr
[
1
].
type
,
acc
,
rhs
);
accumulate
(
expr
[
1
].
type
,
acc
,
rhs
);
for
(
int
i
=
3
;
i
<
expr
.
size
();
i
+=
2
)
{
for
(
int
i
=
3
;
i
<
expr
.
size
();
i
+=
2
)
{
Node
rhs
(
eval
(
expr
[
i
+
1
],
env
));
Node
rhs
(
eval
(
expr
[
i
+
1
],
env
,
f_env
));
accumulate
(
expr
[
i
].
type
,
acc
,
rhs
);
accumulate
(
expr
[
i
].
type
,
acc
,
rhs
);
}
}
return
acc
.
size
()
==
1
?
acc
[
0
]
:
acc
;
return
acc
.
size
()
==
1
?
acc
[
0
]
:
acc
;
...
@@ -139,7 +131,6 @@ namespace Sass {
...
@@ -139,7 +131,6 @@ namespace Sass {
Token
hext
(
Token
::
make
(
expr
.
content
.
token
.
begin
+
1
,
expr
.
content
.
token
.
end
));
Token
hext
(
Token
::
make
(
expr
.
content
.
token
.
begin
+
1
,
expr
.
content
.
token
.
end
));
if
(
hext
.
length
()
==
6
)
{
if
(
hext
.
length
()
==
6
)
{
for
(
int
i
=
0
;
i
<
6
;
i
+=
2
)
{
for
(
int
i
=
0
;
i
<
6
;
i
+=
2
)
{
// Node thing(expr.line_number, static_cast<double>(std::strtol(string(hext.begin+i, 2).c_str(), NULL, 16)));
triple
<<
Node
(
expr
.
line_number
,
static_cast
<
double
>
(
std
::
strtol
(
string
(
hext
.
begin
+
i
,
2
).
c_str
(),
NULL
,
16
)));
triple
<<
Node
(
expr
.
line_number
,
static_cast
<
double
>
(
std
::
strtol
(
string
(
hext
.
begin
+
i
,
2
).
c_str
(),
NULL
,
16
)));
}
}
}
}
...
@@ -155,6 +146,11 @@ namespace Sass {
...
@@ -155,6 +146,11 @@ namespace Sass {
return
env
[
expr
.
content
.
token
];
return
env
[
expr
.
content
.
token
];
}
break
;
}
break
;
case
Node
:
:
function_call
:
{
// TO DO: default-constructed Function should be a generic callback
return
apply_function
(
f_env
[
expr
[
0
].
content
.
token
.
to_string
()],
expr
[
1
],
env
,
f_env
);
}
break
;
default:
{
default:
{
return
expr
;
return
expr
;
}
}
...
@@ -251,46 +247,66 @@ namespace Sass {
...
@@ -251,46 +247,66 @@ namespace Sass {
}
}
}
}
Node
apply
(
Node
&
mixin
,
const
Node
&
args
,
Environment
&
env
)
Node
apply
_mixin
(
Node
&
mixin
,
const
Node
&
args
,
Environment
&
env
,
map
<
string
,
Function
>&
f_
env
)
{
{
// cerr << "APPLYING MIXIN: " << string(mixin[0].token) << endl;
Node
params
(
mixin
[
1
]);
Node
params
(
mixin
[
1
]);
Node
body
(
mixin
[
2
].
clone
());
Node
body
(
mixin
[
2
].
clone
());
Environment
m_env
;
Environment
bindings
;
// bind arguments
// bind arguments
for
(
int
i
=
0
,
j
=
0
;
i
<
args
.
size
();
++
i
)
{
for
(
int
i
=
0
,
j
=
0
;
i
<
args
.
size
();
++
i
)
{
if
(
args
[
i
].
type
==
Node
::
assignment
)
{
if
(
args
[
i
].
type
==
Node
::
assignment
)
{
Node
arg
(
args
[
i
]);
Node
arg
(
args
[
i
]);
Token
name
(
arg
[
0
].
content
.
token
);
Token
name
(
arg
[
0
].
content
.
token
);
if
(
!
m_env
.
query
(
name
))
{
if
(
!
bindings
.
query
(
name
))
{
m_env
[
name
]
=
eval
(
arg
[
1
],
env
);
bindings
[
name
]
=
eval
(
arg
[
1
],
env
,
f_
env
);
}
}
}
}
else
{
else
{
// TO DO: ensure (j < params.size())
// TO DO: ensure (j < params.size())
Node
param
(
params
[
j
]);
Node
param
(
params
[
j
]);
Token
name
(
param
.
type
==
Node
::
variable
?
param
.
content
.
token
:
param
[
0
].
content
.
token
);
Token
name
(
param
.
type
==
Node
::
variable
?
param
.
content
.
token
:
param
[
0
].
content
.
token
);
m_env
[
name
]
=
eval
(
args
[
i
],
env
);
bindings
[
name
]
=
eval
(
args
[
i
],
env
,
f_
env
);
++
j
;
++
j
;
}
}
}
}
// cerr << "BOUND ARGS FOR " << string(mixin[0].token) << endl;
// plug the holes with default arguments if any
// plug the holes with default arguments if any
for
(
int
i
=
0
;
i
<
params
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
params
.
size
();
++
i
)
{
if
(
params
[
i
].
type
==
Node
::
assignment
)
{
if
(
params
[
i
].
type
==
Node
::
assignment
)
{
Node
param
(
params
[
i
]);
Node
param
(
params
[
i
]);
Token
name
(
param
[
0
].
content
.
token
);
Token
name
(
param
[
0
].
content
.
token
);
if
(
!
m_env
.
query
(
name
))
{
if
(
!
bindings
.
query
(
name
))
{
m_env
[
name
]
=
eval
(
param
[
1
],
env
);
bindings
[
name
]
=
eval
(
param
[
1
],
env
,
f_
env
);
}
}
}
}
}
}
// cerr << "BOUND DEFAULT ARGS FOR " << string(mixin[0].token) << endl;
// lexically link the new environment and eval the mixin's body
m_env
.
link
(
env
.
global
?
*
env
.
global
:
env
);
bindings
.
link
(
env
.
global
?
*
env
.
global
:
env
);
// cerr << "LINKED ENVIRONMENT FOR " << string(mixin[0].token) << endl << endl;
for
(
int
i
=
0
;
i
<
body
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
body
.
size
();
++
i
)
{
body
[
i
]
=
eval
(
body
[
i
],
m
_env
);
body
[
i
]
=
eval
(
body
[
i
],
bindings
,
f
_env
);
}
}
return
body
;
return
body
;
}
}
Node
apply_function
(
const
Function
&
f
,
const
Node
&
args
,
Environment
&
env
,
map
<
string
,
Function
>&
f_env
)
{
Node
params
(
f
.
parameters
);
Environment
bindings
;
// bind arguments
for
(
int
i
=
0
,
j
=
0
;
i
<
args
.
size
();
++
i
)
{
if
(
args
[
i
].
type
==
Node
::
assignment
)
{
Node
arg
(
args
[
i
]);
Token
name
(
arg
[
0
].
content
.
token
);
bindings
[
name
]
=
eval
(
arg
[
1
],
env
,
f_env
);
}
else
{
// TO DO: ensure (j < params.size())
Node
param
(
params
[
j
]);
Token
name
(
param
.
type
==
Node
::
variable
?
param
.
content
.
token
:
param
[
0
].
content
.
token
);
bindings
[
name
]
=
eval
(
args
[
i
],
env
,
f_env
);
++
j
;
}
}
return
f
(
bindings
);
}
}
}
\ No newline at end of file
eval_apply.hpp
View file @
b7df7897
...
@@ -11,9 +11,10 @@
...
@@ -11,9 +11,10 @@
namespace
Sass
{
namespace
Sass
{
using
std
::
map
;
using
std
::
map
;
Node
eval
(
Node
&
expr
,
Environment
&
env
);
Node
eval
(
Node
&
expr
,
Environment
&
env
,
map
<
string
,
Function
>&
f_env
);
Node
accumulate
(
Node
::
Type
op
,
Node
&
acc
,
Node
&
rhs
);
Node
accumulate
(
Node
::
Type
op
,
Node
&
acc
,
Node
&
rhs
);
double
operate
(
Node
::
Type
op
,
double
lhs
,
double
rhs
);
double
operate
(
Node
::
Type
op
,
double
lhs
,
double
rhs
);
Node
apply
(
Node
&
mixin
,
const
Node
&
args
,
Environment
&
env
);
Node
apply_mixin
(
Node
&
mixin
,
const
Node
&
args
,
Environment
&
env
,
map
<
string
,
Function
>&
f_env
);
Node
apply_function
(
const
Function
&
f
,
const
Node
&
args
,
Environment
&
env
,
map
<
string
,
Function
>&
f_env
);
}
}
\ No newline at end of file
functions.cpp
0 → 100644
View file @
b7df7897
#include "functions.hpp"
#include "node.hpp"
namespace
Sass
{
Node
rgb
(
const
Environment
&
bindings
)
{
}
\ No newline at end of file
functions.hpp
0 → 100644
View file @
b7df7897
namespace
Sass
{
struct
Environment
;
struct
Function
{
typedef
Node
(
*
Primitive
)(
const
Node
&
,
const
Environment
&
);
string
name
;
Node
parameters
;
Primitive
primitive
;
Function
()
{
}
Function
(
string
name
,
Node
parameters
,
Primitive
primitive
)
:
name
(
name
),
parameters
(
parameters
),
primitive
(
primitive
)
{
}
Node
operator
()(
const
Environment
&
bindings
)
const
{
return
primitive
(
parameters
,
bindings
);
}
};
}
sassc.cpp
View file @
b7df7897
...
@@ -29,12 +29,14 @@ int main(int argc, char* argv[]) {
...
@@ -29,12 +29,14 @@ int main(int argc, char* argv[]) {
}
}
Document
doc
(
path
,
0
);
Document
doc
(
path
,
0
);
cerr
<<
"PREPARING TO PARSE DOCUMENT"
<<
endl
;
cerr
<<
"INITIALIZED DOCUMENT OBJECT"
<<
endl
;
doc
.
parse_scss
();
doc
.
parse_scss
();
cerr
<<
"SUCCESSFULLY PARSED DOCUMENT"
<<
endl
;
cerr
<<
"PARSED DOCUMENT"
<<
endl
;
// doc.eval_pending();
eval
(
doc
.
root
,
doc
.
context
.
global_env
);
eval
(
doc
.
root
,
doc
.
context
.
global_env
,
doc
.
context
.
function_env
);
cerr
<<
"SUCCESSFULLY EVALED DOCUMENT"
<<
endl
;
cerr
<<
"EVALUATED DOCUMENT"
<<
endl
;
string
output
=
doc
.
emit_css
(
style
);
string
output
=
doc
.
emit_css
(
style
);
// cerr << "Fresh nodes:\t" << Node::fresh << endl;
// cerr << "Fresh nodes:\t" << Node::fresh << endl;
...
...
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