scc 2+2 4
At bash prompt - expression evaluated and printed:
scc 2+2 4
If expression is not terminated with semicolon, it is sent to std::cout. If snippet have bash special characters, it must be in single or double quotes. If expression starts with minus, end-of-options indicator -- must be used:
scc '"hello world"'
hello world
scc -- -42
-42
scc "bitset<8>('a')"
01100001
scc 'double x=0.5; sin(x)'
0.479426
echo "ABC" | scc 'char c; while (cin>>c) cout << tolower(c);'
abc
If double semicolon ;; is present, then what come before it is goes before main (into the file scope):
scc 'int f(int i) {return i+i;} ;; f(10)'
20
Snippet is evaluated in environment where most of C++ Standard Library includes are included and most STD entities are imported into default namespace with using std::...;
If you need only plain C++ REPL, that is about all you need to know. You can skip to install section now.
Sections that follow are about SCC optional modules.
Range Operators (headers only library) was recently split off SCC. It can be useful if you use STL containers, strings and want simpler replacement for std::cout.
Some examples of what it can do:
// Can print ranges, container, tuples, etc directly (vint is vector<int>) :
scc 'vint V{1,2,3}; V'
{1,2,3}
// Classic pipe. These are std:: alogorithms
scc 'vint{3,1,2,3} | sort | unique | reverse'
{3, 2, 1}
// Assign 42 to 2..5
scc 'vint V=range(0,9); range(V/2, V/5) = 42; V'
{0, 1, 42, 42, 42, 5, 6, 7, 8, 9}
// Find (brute force algorithm) maximum of `cos(x)` in interval: `8 < x < 9`:
scc 'range(8, 9, 0.01) * cos || max'
-0.1455
// Integrate sin(x) from 0 to pi
scc 'auto d=0.001; (range(0,pi,d) * sin || add) * d'
2
// Concatenate vector of strings ('add' is shoftcut for std::plus<T>()):
scc 'vstr V{"aaa", "bb", "cccc"}; V || add'
aaabbcccc
// Total length of strings in vector of strings
scc 'vstr V{"aaa", "bb", "cccc"}; V * size || add'
9
// Assign to c-string, then append `"XYZ"` and then remove `"bc"` substring :
scc 'char s[99]; range(s) = "abc"; (range(s) << "XYZ") - "bc"'
aXYZ
// Remove non alpha-num characters and convert to upper case
scc '(range("abc-123, xyz/") | isalnum) * toupper'
ABC123XYZ
// Hide phone number:
scc "str S=\"John Q Public (650)1234567\"; S|isdigit='X'; S"
John Q Public (XXX)XXXXXXX
Requires: C++11 compiler. Tested with GCC-4.7.2, GCC-4.8(pre release), CLANG-3.2(pre release)
In order to use it, you need to install it, and tell SCC where to look for its include files if it is installed in directory which is not searched by default by compiler.
Options -s / -S can enable/disable this module. Set environment variable scc_RO (to any value) enables it.
If enabled its print operator will be used instead of std::cout to print last statement-expression.
Shortcuts are typedefs and macros to cut verbosity. For example:
WRL --> while(read_line()) str --> std::string lint --> std::list<int> vint --> std::vector<int> dint --> std::deque<int> dfloat --> std::deque<float> ...
Some variables are pre-defined:
i, j, k, n, m — long, initialized to 0
x, y, z — double, initialized to 0
s, w — std::string
c — char
p — char*
You don’t need to remember these. Predefined variables are defined in external to snippet scope, so you can re-define these to what ever you want.
This is module that is bundled with SCC. It can be disabled if for example your compiler can not compile it for some reason. Options -a / -A enable/disable it. Set environment variable scc_AWK (to any value) enables it.
AWK module allows stream processing - similar to real AWK.
Syntax is not exactly AWK’s, it is still C++ , but it is quite similar.
Biggest difference is script layout. AWK’s script have following elements (simplified):
awk 'BEGIN{begin-expr}; {per-record-expr}; END{end-expr}'
SCC have two alternatives for above. First is explicit while-loop:
scc 'begin-expr; WRL per-record-expr; end-expr;'
Shortcut WRL expands to while(read_line()). Function read_line(), reads input line and splits it into fields.
Second alternative is to use options -n and -p. With -n, record is read, split into fields and snippet is evaluated for every record. With -p, additionally all fields are printed after snippet was evaluated. These are equivalent to PERL’s and are convenient when we do not have begin-expr and end-expr.
scc -n 'per-record-expr;'
Fortunately, GCC and CLANG allows use of $ in identifiers, so AWK’s dollar variables ($0, $1, $NF) are valid in SCC.
In SCC, line’s fields are of special string type fld, it is similar to std::string but it can be used in arithmetic expressions - they can be implicitly converted to corresponding numeric type. And it can be assigned a numeric value. That is fld behave like AWK’s vars. Numeric types are any of int, float, etc.
fld f("1");
int i;
i = f; // 1
i = f+1; // 2
f = 2; // "2"
f + " m/s" // "2 m/s"
f + 5 // "7"
SCC supports following AWK’s global variables:
$ - derived from std::deque<fld> — line’s fields
NF - long, number of fields (set after read_line())
NR - long, number of records read so far (set after read_line())
OFS - strr, output field separator (another special type - string reference).
FS - strr, input field separator.
ORS - strr, output record separator
RS - strr, input record separator.
FILENAME - const char[], current filename being processed
More examples. Sum-up DF(1) used-disk-space column. In AWK and SCC:
df | awk '{n+=$3}; END{print n}'
31399199
df | scc 'WRL n+=$3; n'
31399199
We can also replace column number with symbolic name (from df output header):
df | scc -H 'WRL n+=$("Used"); n'
31399199
Prepend line number to every line.
echo -e 'aaa\nbbb' | scc -p NR 1 aaa 2 bbb
For every line: first NR is printed (notice that there is no semicolon), then $0.
Now lets make comma separated fields out of colon separated. Option -o sets OFS (output field separator), -F - set FS Snippet is empty in this example.
echo 1:2:3 | scc -F: -o, -p 1,2,3
Or equivalent:
echo 1:2:3 | FS=: OFS=, scc -p 1,2,3
git clone http://github.com/lvv/scc scc cd scc echo "PATH+=:$PWD/scc/" >> ~/.profile . ~/.profile scc '"SCC is installed"'
With no or empty config, all optional modules will be disabled, and default compiler will be GCC.
There is scc/example_config which you can copy (and edit) into one of: /etc/scc, ~/.scc or .scc.
For GCC you can enable precompiled headers, which will allow slightly (20%) faster compile. This is not recommended if you are going to update SCC or GCC. Command scc -r will create directory .gch with precompiled headers:
cd path-to-scc-home scc --make-gch ls -l .gch
You need re-generate pre-compiled headers if SCC or GCC install was modified. To disable pre-compiled headers, run rm -rf gch.
Parser which extracts last C++ statement from snippet is semi-broken. It sometimes incorrectly parse (to extract last expression) multi-line scripts or expressions with "{}". See u-sed file for details. As workaround terminate every line with semicolon (even comment-line) and do not use print-if-not-terminated-with-semicolon feature.
Regex in RS/FS are currently not supported (but were in v0.1)
AWK module should be fixed to handle white space exactly like AWK.