Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #62 from sjp/r-support

R support
  • Loading branch information...
commit 4acbe34014e901651d7b2e908cbb547446c2eac9 2 parents 1a3b4cf + b27f00e
@ccampbell authored
View
1  README.md
@@ -66,6 +66,7 @@ Currently supported languages are:
- Lua
- C#
- Smalltalk
+- R
## More Info
View
60 demos/r.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>R Demo</title>
+ <link href="../themes/tomorrow-night.css" rel="stylesheet">
+ </head>
+ <body>
+ <pre>
+<code data-language="r">## Probability density function for the Generalised Normal Laplace distribution
+dgnl &lt;- function(x, mu = 0, sigma = 1, alpha = 1, beta = 1, rho = 1,
+ param = c(mu, sigma, alpha, beta, rho)) {
+
+ ## check parameters
+ parResult &lt;- gnlCheckPars(param)
+ case &lt;- parResult$case
+ errMessage &lt;- parResult$errMessage
+
+ if (case == "error")
+ stop(errMessage)
+
+ mu &lt;- param[1]
+ sigma &lt;- param[2]
+ alpha &lt;- param[3]
+ beta &lt;- param[4]
+ rho &lt;- param[5]
+
+ ## Shifting by mu
+ x &lt;- x - mu
+
+ ## Initialising result vector
+ pdfValues &lt;- rep(0, length(x))
+
+ ## Because 'integrate' doesn't take vectors as input, we need to iterate over
+ ## x to evaluate densities
+ for (i in 1:length(x)) {
+ ## Modified characteristic function. Includes minor calculation regarding
+ ## complex numbers to ensure the function returns a real number
+ chfn &lt;- function(s) {
+ result &lt;- (alpha * beta * exp(-((sigma^2 * s^2) / 2))) /
+ (complex(real = alpha, imaginary = -s) *
+ complex(real = beta, imaginary = s))
+ result &lt;- result^rho ## Scaling result by rho
+ r &lt;- Mod(result)
+ theta &lt;- Arg(result)
+ r * cos(theta - (s * x[i]))
+ }
+
+ ## Integrating modified characteristic function
+ pdfValues[i] &lt;- (1 / pi) * integrate(chfn, 0, Inf)$value
+ }
+
+ ## Returning vector of densities
+ pdfValues
+}
+</code></pre>
+ <script src="../js/rainbow.js"></script>
+ <script src="../js/language/generic.js"></script>
+ <script src="../js/language/r.js"></script>
+ </body>
+</html>
View
86 js/language/r.js
@@ -0,0 +1,86 @@
+/**
+ * R language patterns
+ *
+ * @author Simon Potter
+ * @version 1.0
+ */
+Rainbow.extend('r', [
+ /**
+ * Note that a valid variable name is of the form:
+ * [.a-zA-Z][0-9a-zA-Z._]*
+ */
+ {
+ 'matches': {
+ 1: {
+ 'name': 'keyword.operator',
+ 'pattern': /\=|<\-|&lt;-/g
+ },
+ 2: {
+ 'name': 'string',
+ 'matches': {
+ 'name': 'constant.character.escape',
+ 'pattern': /\\('|"){1}/g
+ }
+ }
+ },
+ 'pattern': /(\(|\s|\[|\=|:)(('|")([^\\\1]|\\.)*?(\3))/gm
+ },
+ /**
+ * Most of these are known via the Language Reference.
+ * The built-in constant symbols are known via ?Constants.
+ */
+ {
+ 'matches': {
+ 1: 'constant.language'
+ },
+ 'pattern': /\b(NULL|NA|TRUE|FALSE|T|F|NaN|Inf|NA_integer_|NA_real_|NA_complex_|NA_character_)\b/g
+ },
+ {
+ 'matches': {
+ 1: 'constant.symbol'
+ },
+ 'pattern': /[^0-9a-zA-Z\._](LETTERS|letters|month\.(abb|name)|pi)/g
+ },
+ /**
+ * @todo: The list subsetting operator isn't quite working properly.
+ * It includes the previous variable when it should only match [[
+ */
+ {
+ 'name': 'keyword.operator',
+ 'pattern': /&lt;-|<-|-|==|&lt;=|<=|&gt;>|>=|<|>|&amp;&amp;|&&|&amp;|&|!=|\|\|?|\*|\+|\^|\/|%%|%\/%|\=|%in%|%\*%|%o%|%x%|\$|:|~|\[{1,2}|\]{1,2}/g
+ },
+ {
+ 'matches': {
+ 1: 'storage',
+ 3: 'entity.function'
+ },
+ 'pattern': /(\s|^)(.*)(?=\s?=\s?function\s\()/g
+ },
+ {
+ 'matches': {
+ 1: 'storage.function'
+ },
+ 'pattern': /[^a-zA-Z0-9._](function)(?=\s*\()/g
+ },
+ {
+ 'matches': {
+ 1: 'namespace',
+ 2: 'keyword.operator',
+ 3: 'function.call'
+ },
+ 'pattern': /([a-zA-Z][a-zA-Z0-9._]+)([:]{2,3})([.a-zA-Z][a-zA-Z0-9._]*(?=\s*\())\b/g
+ },
+ /*
+ * Note that we would perhaps match more builtin functions and
+ * variables, but there are so many that most are ommitted for now.
+ * See ?builtins for more info.
+ *
+ * @todo: Fix the case where we have a function like tmp.logical().
+ * This should just be a function call, at the moment it's
+ * only partly a function all.
+ */
+ {
+ 'name': 'support.function',
+ 'pattern': /(^|[^0-9a-zA-Z\._])(array|character|complex|data\.frame|double|integer|list|logical|matrix|numeric|vector)(?=\s*\()/g
+ }
+]);
View
1  tests/index.html
@@ -16,6 +16,7 @@
<option selected value="javascript">javascript</option>
<option selected value="php">php</option>
<option selected value="python">python</option>
+ <option selected value="r">r</option>
<option selected value="ruby">ruby</option>
<option selected value="shell">shell</option>
<option selected value="smalltalk">smalltalk</option>
View
114 tests/language/r-test.js
@@ -0,0 +1,114 @@
+/**
+ * R tests
+ *
+ * @author Simon Potter
+ */
+RainbowTester.startTest('r');
+
+RainbowTester.run(
+ 'comments',
+
+ '# A comment\n' +
+ 'a <- "b" # Another comment',
+
+ '<span class="comment"># A comment</span>\n' +
+ 'a <span class="keyword operator">&lt;-</span> <span class="string">"b"</span> <span class="comment"># Another comment</span>'
+);
+
+RainbowTester.run(
+ 'assignment',
+
+ 'foo.bar <- "foo"\n' +
+ 'baz1 = 1.62e-4',
+
+ 'foo.bar <span class="keyword operator">&lt;-</span> <span class="string">"foo"</span>\n' +
+ 'baz1 <span class="keyword operator">=</span> <span class="constant numeric">1.62e-4</span>'
+);
+
+RainbowTester.run(
+ 'constants',
+
+ 'baz <- NA\n' +
+ 'my.pi <- pi\n' +
+ 'all.letters <- c(LETTERS, letters)\n' +
+ 'xrange <- c(-Inf, TRUE)',
+
+ 'baz <span class="keyword operator">&lt;-</span> <span class="constant language">NA</span>\n' +
+ 'my.pi <span class="keyword operator">&lt;-</span> <span class="constant symbol">pi</span>\n' +
+ 'all.letters <span class="keyword operator">&lt;-</span> <span class="function call">c</span>(<span class="constant symbol">LETTERS</span>, <span class="constant symbol">letters</span>)\n' +
+ 'xrange <span class="keyword operator">&lt;-</span> <span class="function call">c</span>(<span class="keyword operator">-</span><span class="constant language">Inf</span>, <span class="constant language">TRUE</span>)'
+);
+
+RainbowTester.run(
+ 'operators',
+
+ 'beta.hat <- solve(t(X) %*% X) %*% t(X) %*% y\n' +
+ 'bound.rect <- grid::rectGrob()\n' +
+ 'my_seq <- 1:10\n' +
+ 'is_in_seq <- c(2, 7, 23) %in% my_seq\n' +
+ 'plot(y ~ x, type = "l")',
+
+ 'beta.hat <span class="keyword operator">&lt;-</span> <span class="function call">solve</span>(<span class="function call">t</span>(X) <span class="keyword operator">%*%</span> X) <span class="keyword operator">%*%</span> <span class="function call">t</span>(X) <span class="keyword operator">%*%</span> y\n' +
+ 'bound.rect <span class="keyword operator">&lt;-</span> <span class="namespace">grid</span><span class="keyword operator">::</span><span class="function call">rectGrob</span>()\n' +
+ 'my_seq <span class="keyword operator">&lt;-</span> <span class="constant numeric">1</span><span class="keyword operator">:</span><span class="constant numeric">10</span>\n' +
+ 'is_in_seq <span class="keyword operator">&lt;-</span> <span class="function call">c</span>(<span class="constant numeric">2</span>, <span class="constant numeric">7</span>, <span class="constant numeric">23</span>) <span class="keyword operator">%in%</span> my_seq\n' +
+ '<span class="function call">plot</span>(y <span class="keyword operator">~</span> x, type <span class="keyword operator">=</span> <span class="string">"l"</span>)'
+);
+
+/**
+ * Note that the second function is intentionally not a function call,
+ * just testing that the regex is matching only 'function' and not .+function
+ */
+RainbowTester.run(
+ 'function creation',
+
+ 'square <- function(x) x * x\n' +
+ 'square2 <- testfunction(x) x * x\n' +
+ 'area <- function (r) {\n' +
+ ' pi * r^2\n' +
+ '}',
+
+ 'square <span class="keyword operator">&lt;-</span> <span class="storage function">function</span>(x) x <span class="keyword operator">*</span> x\n' +
+ 'square2 <span class="keyword operator">&lt;-</span> <span class="function call">testfunction</span>(x) x <span class="keyword operator">*</span> x\n' +
+ 'area <span class="keyword operator">&lt;-</span> <span class="storage function">function</span> (r) {\n' +
+ ' <span class="constant symbol">pi</span> <span class="keyword operator">*</span> r<span class="keyword operator">^</span><span class="constant numeric">2</span>\n' +
+ '}'
+);
+
+RainbowTester.run(
+ 'variable',
+
+ 'tmp <- 1\n' +
+ 'another.tmp <- 2\n' +
+ 'this.is.a.var <- 3',
+
+ 'tmp <span class="keyword operator">&lt;-</span> <span class="constant numeric">1</span>\n' +
+ 'another.tmp <span class="keyword operator">&lt;-</span> <span class="constant numeric">2</span>\n' +
+ 'this.is.a.var <span class="keyword operator">&lt;-</span> <span class="constant numeric">3</span>'
+);
+
+RainbowTester.run(
+ 'subsetting',
+
+ 'tmp[1]\n' +
+ 'tmp[["test"]]',
+
+ 'tmp<span class="keyword operator">[</span><span class="constant numeric">1</span><span class="keyword operator">]</span>\n' +
+ 'tmp<span class="keyword operator">[[</span><span class="string">"test"</span><span class="keyword operator">]]</span>'
+);
+
+RainbowTester.run(
+ 'support functions',
+
+ 'logical(10)\n' +
+ 'test.logical(10)\n' +
+ 'data.frame(a = 1:10, b = 15:24)\n' +
+ 'complex(real = 1, imaginary = 0.5)',
+
+ '<span class="support function">logical</span>(<span class="constant numeric">10</span>)\n' +
+ '<span class="function call">test.logical</span>(<span class="constant numeric">10</span>)\n' +
+ '<span class="support function">data.frame</span>(a <span class="keyword operator">=</span> <span class="constant numeric">1</span><span class="keyword operator">:</span><span class="constant numeric">10</span>, b <span class="keyword operator">=</span> <span class="constant numeric">15</span><span class="keyword operator">:</span><span class="constant numeric">24</span>)\n' +
+ '<span class="support function">complex</span>(real <span class="keyword operator">=</span> <span class="constant numeric">1</span>, imaginary <span class="keyword operator">=</span> <span class="constant numeric">0.5</span>)'
+);
+
+RainbowTester.endTest('r');
View
1  util/builder.py
@@ -22,6 +22,7 @@ def __init__(self, js_path, closure_path, theme_path=None):
'lua': '1.0',
'php': '1.0.5',
'python': '1.0.6',
+ 'r': '1.0',
'ruby': '1.0.5',
'scheme': '1.0',
'shell': '1.0.3',
Please sign in to comment.
Something went wrong with that request. Please try again.