In my little game project, i want player to manipulate some in-game stuff writing some Clojure scripts right in the game. So, i downloaded Clojure lib and used this code:
private val eval = Clojure.`var`("clojure.core", "eval")
fun eval(code: String): Any? =
try {
eval.invoke(Clojure.read("(do $code)"))
} catch(e: Exception) {
e.printStackTrace()
null
}
but the thing is, by doing so player can manipulate the whole program, as it is runs in same environment, as the game code. The simplest example is (System/exit 0).
My question is - how to remove all Clojure bindings from my scripting context except some basic predefined stuff, like math operators, collection magic and so on?
Also, i can put my own bindings(for wiring these scripts to actual game logic) with eval.invoke("(def do-magic [x] (println "magic"))"), but is there a more consistent way to do this?
upd:
I need to do really simple stuff like math and jumping around with simple functions. Maybe a bit of collection magic. So i need to block everything except this stuff, so any unsafe code just cant exist at all.
This technique is called sandbox and simply googling "clojure sandbox" finally led me to the articles about this topic.
UPD:
I've needed to whitelist stuff, not blacklist as it was used on the internet.
Spent whole day, but finally got this to work properly
private val eval = Clojure.`var`("clojure.core", "eval")
val whitelist = listOf("+", "-", "*", "/", "=") // example
init {
val wh = whitelist.joinToString(" ", "[", "]") { "\"$it\"" }
eval("""
(let [wh (vec (map symbol $wh))]
(doseq [n (all-ns) :let [n (ns-name n)]]
(if (= (str n) "clojure.core")
(doseq [[k _] (ns-map n) :when (not (some (fn [x] (= x k)) wh))]
(ns-unmap n k))
(remove-ns n))))
""")
}
fun eval(code: String): Any? =
try {
eval.invoke(Clojure.read("(do $code)"))
} catch(e: Exception) {
e.printStackTrace()
null
}
Related
Consider the grammar:
TOP ⩴ 'x' Y 'z'
Y ⩴ 'y'
Here's how to get the exact value ["TOP","x",["Y","y"],"z"] with various parsers (not written manually, but generated from the grammar):
xyz__Parse-Eyapp.eyp
%strict
%tree
%%
start:
TOP { shift; use JSON::MaybeXS qw(encode_json); print encode_json $_[0] };
TOP:
'x' Y 'z' { shift; ['TOP', (scalar #_) ? #_ : undef] };
Y:
'y' { shift; ['Y', (scalar #_) ? #_ : undef] };
%%
xyz__Regexp-Grammars.pl
use 5.028;
use strictures;
use Regexp::Grammars;
use JSON::MaybeXS qw(encode_json);
print encode_json $/{TOP} if (do { local $/; readline; }) =~ qr{
<nocontext:>
<TOP>
<rule: TOP>
<[anon=(x)]> <[anon=Y]> <[anon=(z)]>
<MATCH=(?{['TOP', $MATCH{anon} ? $MATCH{anon}->#* : undef]})>
<rule: Y>
<[anon=(y)]>
<MATCH=(?{['Y', $MATCH{anon} ? $MATCH{anon}->#* : undef]})>
}msx;
Code elided for the next two parsers. With Pegex, the functionality is achieved by inheriting from Pegex::Receiver. With Marpa-R2, the customisation of the return value is quite limited, but nested arrays are possible out of the box with a configuration option.
I have demonstrated that the desired customisation is possible, although it's not always easy or straight-forward. These pieces of code attached to the rules are run as the tree is assembled.
The parse method returns nothing but nested Match objects that are unwieldy. They do not retain the unnamed terminals! (Just to make sure what I'm talking about: these are the two pieces of data at the RHS of the TOP rule whose values are 'x' and 'z'.) Apparently only data springing forth from named declarators are added to the tree.
Assigning to the match variable (analog to how it works in Regexp-Grammars) seems to have no effect. Since the terminals do no make it into the match variable, actions don't help, either.
In summary, here's the grammar and ordinary parse value:
grammar {rule TOP { x <Y> z }; rule Y { y };}.parse('x y z')
How do you get the value ["TOP","x",["Y","y"],"z"] from it? You are not allowed to change the shape of rules because that would potentially spoil user attached semantics, otherwise anything else is fair game. I still think the key to the solution is the match variable, but I can't see how.
Not a full answer, but the Match.chunks method gives you a few of the input string tokenized into captured and non-captured parts.
It does, however, does not give you the ability to distinguish between non-capturing literals in the regex and implicitly matched whitespace.
You could circumvent that by adding positional captures, and use Match.caps
my $m = grammar {rule TOP { (x) <Y> (z) }; rule Y { (y) }}.parse('x y z');
sub transform(Pair $p) {
given $p.key {
when Int { $p.value.Str }
when Str { ($p.key, $p.value.caps.map(&transform)).flat }
}
}
say $m.caps.map(&transform);
This produces
(x (Y y) z)
so pretty much what you wanted, except that the top-level TOP is missing (which you'll likely only get in there if you hard-code it).
Note that this doesn't cover all edge cases; for example when a capture is quantified, $p.value is an Array, not a match object, so you'll need another level of .map in there, but the general idea should be clear.
I'm playing around with StructuredFormatDisplay and I assumed I could use multiple properties for the Value, but it seems that is not the case. This question (and accepted answer) talk about customizing in general, but the examples given only use a single property. MSDN is not helpful when it comes to usage of this attribute.
Here's my example:
[<StructuredFormatDisplay("My name is {First} {Last}")>]
type Person = {First:string; Last:string}
If I then try this:
let johnDoe = {First="John"; Last="Doe"}
I end up with this error:
<StructuredFormatDisplay exception: Method 'FSI_0038+Person.First}
{Last' not found.>
The error seems to hint at it only capturing the first property mentioned in my Value but it's hard for me to say that with any confidence.
I have figured out I can work around this by declaring my type like this:
[<StructuredFormatDisplay("My name is {Combined}")>]
type Person = {First:string; Last:string} with
member this.Combined = this.First + " " + this.Last
But I was wondering if anyone could explain why I can't use more than one property, or if you can, what syntax I'm missing.
I did some digging in the source and found this comment:
In this version of F# the only valid values are of the form PreText
{PropertyName} PostText
But I can't find where that limitation is actually implemented, so perhaps someone more familiar with the code base could simply point me to where this limitation is implemented and I'd admit defeat.
The relevant code from the F# repository is in the file sformat.fs, around line 868. Omitting lots of details and some error handling, it looks something like this:
let p1 = txt.IndexOf ("{", StringComparison.Ordinal)
let p2 = txt.LastIndexOf ("}", StringComparison.Ordinal)
if p1 < 0 || p2 < 0 || p1+1 >= p2 then
None
else
let preText = if p1 <= 0 then "" else txt.[0..p1-1]
let postText = if p2+1 >= txt.Length then "" else txt.[p2+1..]
let prop = txt.[p1+1..p2-1]
match catchExn (fun () -> getProperty x prop) with
| Choice2Of2 e ->
Some (wordL ("<StructuredFormatDisplay exception: " + e.Message + ">"))
| Choice1Of2 alternativeObj ->
let alternativeObjL =
match alternativeObj with
| :? string as s -> sepL s
| _ -> sameObjL (depthLim-1) Precedence.BracketIfTuple alternativeObj
countNodes 0 // 0 means we do not count the preText and postText
Some (leftL preText ^^ alternativeObjL ^^ rightL postText)
So, you can easily see that this looks for the first { and the last }, and then picks the text between them. So for foo {A} {B} bar, it extracts the text A} {B.
This does sound like a silly limitation and also one that would not be that hard to improve. So, feel free to open an issue on the F# GitHub page and consider sending a pull request!
Just to put a bow on this, I did submit a PR to add this capability and yesterday it was accepted and pulled into the 4.0 branch.
So starting with F# 4.0, you'll be able to use multiple properties in a StructuredFormatDisplay attribute, with the only downside that all curly braces you wish to use in the message will now need to be escaped by a leading \ (e.g. "I love \{ braces").
I rewrote the offending method to support recursion and switched to using a regular expression to detect property references. It seems to work pretty well, although it isn't the prettiest code I've ever written.
I'm writing a LSL to Lua translator, and I'm having all sorts of trouble implementing incrementing and decrementing operators. LSL has such things using the usual C like syntax (x++, x--, ++x, --x), but Lua does not. Just to avoid massive amounts of typing, I refer to these sorts of operators as "crements". In the below code, I'll use "..." to represent other parts of the expression.
... x += 1 ...
Wont work, coz Lua only has simple assignment.
... x = x + 1 ...
Wont work coz that's a statement, and Lua can't use statements in expressions. LSL can use crements in expressions.
function preIncrement(x) x = x + 1; return x; end
... preIncrement(x) ...
While it does provide the correct value in the expression, Lua is pass by value for numbers, so the original variable is not changed. If I could get this to actually change the variable, then all is good. Messing with the environment might not be such a good idea, dunno what scope x is. I think I'll investigate that next. The translator could output scope details.
Assuming the above function exists -
... x = preIncrement(x) ...
Wont work for the "it's a statement" reason.
Other solutions start to get really messy.
x = preIncrement(x)
... x ...
Works fine, except when the original LSL code is something like this -
while (doOneThing(x++))
{
doOtherThing(x);
}
Which becomes a whole can of worms. Using tables in the function -
function preIncrement(x) x[1] = x[1] + 1; return x[1]; end
temp = {x}
... preincrement(temp) ...
x = temp[1]
Is even messier, and has the same problems.
Starting to look like I might have to actually analyse the surrounding code instead of just doing simple translations to sort out what the correct way to implement any given crement will be. Anybody got any simple ideas?
I think to really do this properly you're going to have to do some more detailed analysis, and splitting of some expressions into multiple statements, although many can probably be translated pretty straight-forwardly.
Note that at least in C, you can delay post-increments/decrements to the next "sequence point", and put pre-increments/decrements before the previous sequence point; sequence points are only located in a few places: between statements, at "short-circuit operators" (&& and ||), etc. (more info here)
So it's fine to replace x = *y++ + z * f (); with { x = *y + z * f(); y = y + 1; }—the user isn't allowed to assume that y will be incremented before anything else in the statement, only that the value used in *y will be y before it's incremented. Similarly, x = *--y + z * f(); can be replaced with { y = y - 1; x = *y + z * f (); }
Lua is designed to be pretty much impervious to implementations of this sort of thing. It may be done as kind of a compiler/interpreter issue, since the interpreter can know that variables only change when a statement is executed.
There's no way to implement this kind of thing in Lua. Not in the general case. You could do it for global variables by passing a string to the increment function. But obviously it wouldn't work for locals, or for variables that are in a table that is itself global.
Lua doesn't want you to do it; it's best to find a way to work within the restriction. And that means code analysis.
Your proposed solution only will work when your Lua variables are all global. Unless this is something LSL also does, you will get trouble translating LSL programs that use variables called the same way in different places.
Lua is only able of modifying one lvalue per statement - tables being passed to functions are the only exception to this rule. You could use a local table to store all locals, and that would help you out with the pre-...-crements; they can be evaluated before the expression they are contained in is evauated. But the post-...-crements have to be evaluated later on, which is simply not possible in lua - at least not without some ugly code involving anonymous functions.
So you have one options: you must accept that some LSL statements will get translated to several Lua statements.
Say you have a LSL statement with increments like this:
f(integer x) {
integer y = x + x++;
return (y + ++y)
}
You can translate this to a Lua statement like this:
function f(x) {
local post_incremented_x = x + 1 -- extra statement 1 for post increment
local y = x + post_incremented_x
x = post_incremented_x -- extra statement 2 for post increment
local pre_incremented_y = y + 1
return y + pre_incremented_y
y = pre_incremented_y -- this line will never be executed
}
So you basically will have to add two statements per ..-crement used in your statements. For complex structures, that will mean calculating the order in which the expressions are evaluated.
For what is worth, I like with having post decrements and predecrements as individual statements in languages. But I consider it a flaw of the language when they can also be used as expressions. The syntactic sugar quickly becomes semantic diabetes.
After some research and thinking I've come up with an idea that might work.
For globals -
function preIncrement(x)
_G[x] = _G[x] + 1
return _G[x]
end
... preIncrement("x") ...
For locals and function parameters (which are locals to) I know at the time I'm parsing the crement that it is local, I can store four flags to tell me which of the four crements is being used in the variables AST structure. Then when it comes time to output the variables definition, I can output something like this -
local x;
function preIncrement_x() x = x + 1; return x; end
function postDecrement_x() local y = x; x = x - 1; return y; end
... preIncrement_x() ...
In most of your assessment of configurability to the code. You are trying to hard pass data types from one into another. And call it a 'translator'. And in all of this you miss regex and other pattern match capacities. Which are far more present in LUA than LSL. And since the LSL code is being passed into LUA. Try using them, along with other functions. Which would define the work more as a translator, than a hard pass.
Yes I know this was asked a while ago. Though, for other viewers of this topic. Never forget the environments you are working in. EVER. Use what they give you to the best ability you can.
I'm giving a small presentation to a group of C/C++ programmers who have very little experience with functional languages. Part of the presentation mentions Erlang, and I would like to give a specific small code example.
There is a ton of awesome information on StackOverflow about how/where Erlang is used and its advantages. One of the most common advantages I see is how it can do a lot with just a little terse code, especially compared to C/C++.
I am looking for a good code snippet of Erlang that simply illustrates these types of benefits. Especially something thats easily done in Erlang with few lines, that would be much more complicated in C/C++.
Anyone have any interesting suggestions?
Check out example 4 for an excellent example of Erlang's bit syntax. I'm sure there are a number of c/c++ developers that will appreciate the brevity of the syntax!
I would use an example which shows how easy it is to do concurrency.
So basically write map-reduce (but never ever use that word to describe it to a C programmer).
You could start with showing a program that plays Fizz Buzz, and then proceed to make it concurrent. Should easily fit a whiteboard, or two pages of powerpoint.
A Co-worker suggested using Merge-Sort as an example:
http://rosettacode.org/wiki/Sorting_algorithms/Merge_sort#Erlang
mergeSort(L) when length(L) == 1 -> L;
mergeSort(L) when length(L) > 1 ->
{L1, L2} = lists:split(length(L) div 2, L),
lists:merge(mergeSort(L1), mergeSort(L2)).
Multi-process version:
pMergeSort(L) when length(L) == 1 -> L;
pMergeSort(L) when length(L) > 1 ->
{L1, L2} = lists:split(length(L) div 2, L),
spawn(mergesort, pMergeSort2, [L1, self()]),
spawn(mergesort, pMergeSort2, [L2, self()]),
mergeResults([]).
pMergeSort2(L, Parent) when length(L) == 1 -> Parent ! L;
pMergeSort2(L, Parent) when length(L) > 1 ->
{L1, L2} = lists:split(length(L) div 2, L),
spawn(mergesort, pMergeSort2, [L1, self()]),
spawn(mergesort, pMergeSort2, [L2, self()]),
Parent ! mergeResults([]).
Pythagorean Triples. Get all number combinations below 30 whereby the 3 numbers make a right angled triangle as it is according to Pythagoras.
[{X,Y,Z} || X <- lists:seq(1,30),
Y <- lists:seq(1,30),
Z <- lists:seq(1,30), ((X * X) + (Y * Y)) == (Z * Z)].
Try doing that in C/C++ , or Java and see if you will avoid a for loop if not more than one depending on your skill level :)
the factorial code snippet is the best i have always used to show how short erlang programs can be
-module(factorial).
-export([calculate/1]).
calculate(0) -> 1;
calculate(N) -> N * calculate(N -1).
As simple as that. That short program illustrates not only how short Erlang programs can be, But also: Pattern Matching, Function Clauses and Last Call Optimization. I always had a C++ version of the same, below:
#include<iostream.h>
#include<conio.h>
long factorial(unsigned int a);
void main() {
unsigned int a;
long fac;
.....
.....
return factorial(a);
}
long factorial(unsigned int x) {
long fac=1;
if(x == 0) {return 1;}
else {
while(x > 0) {
fac *= x;
x -= 1 ;
}
return fac; }
}
Well, this may not be the shortest C++ version, but i know you get the idea.
I cannot find "do...while..."
I have to code like this:
let bubbleSort a=
let n = Array.length a
let mutable swapped = true
let mutable i = 0
while swapped do
swapped <- false
for j = 0 to n-i-2 do
if a.[j] > a.[j+1] then
let t = a.[j]
a.[j] <- a.[j+1]
a.[j+1] <- t
swapped <- true
i <- i+1
The code is bad without "do...while".
Sadly, "break/continue" are also not available.
F# is very much suitable for non-functional programming. In fact, being able to fine-tune parts of an algorithm in an imperative style is one of the major strong points of the language for me.
For example, in tackling a project euler problem, I started out with a clean functional solution using immutable sets and folds. It took 150 seconds to complete. Now having the framework of my algorithm in place allowed me to pick apart the data structures and folds operations one at a time until I managed to get the run time down to 5 seconds. My final solution was very much an imperative one (and even slightly faster than an equivalent C# version).
As you can see I solved it by coding a solution in functional style first and then rewrite small parts to an imperative style. Not having to deal with indices and other loop conditions explicitly kept the code more understandable for me.
Once you learn how to think like a functional programmer you'll find that you'll rarely want breaks and continues. That's what I experienced. But if you do need them, knowing how to think in a functional way helps in coming up with work-arounds, usually involving a tail-recursive version of what used to be a loop.
By the time you start thinking more in an idiomatic F# way, you'll probably see more and more (tail-)recursive code replacing what you used to do with looping constructs. Heck, writing F# for 2 years now has warped my mind so far that I'm more likely to pick recursion and folds over loops.
Whenever I think I need break/continue, I usually don't because there's a cleaner version of the algorithm hidden and waiting to get out. The biggest challenge is learning how to find that cleaner version. I'm afraid that lots of practice and good examples are the only way to get better at thinking functionally, but I believe that it's an effort well spent.
Edit: ironically, bubble sort is an algorithm which is actually designed for arrays with mutable contents. Any recursive bubble sort is likely to be harder to understand than an imperative version. I think I just killed my own post here.
It turns out to be quite easy to write a good enough do-while in F# as a higher-order function:
let doWhile f c =
f ()
while c () do
f ()
break and continue would be a really useful feature additions; they're reserved words, and maybe we'll see them in a future version of the language. The lack of them is an occasional minor annoyance, but hardly makes the language 'unsuitable'. In the mean time, a mutable sentinel works, as you have in your example.
See also
http://tomasp.net/blog/imperative-ii-break.aspx/
do/while is not available because F# is a functional language and this kind of construct is specific to imperative languages.
break/continue is also not available for the same reasons.
However, you can still write do/while in F#. The following code blocks are equivalent :
in C#
do
{
System.Console.WriteLine("processing something...");
System.Console.WriteLine("doing something complicated");
System.Console.Write("continue?");
} while (Console.ReadLine() == "y");
in F#
let doSomethingAndContinue() =
printfn "processing something..."
printfn "doing something complicated"
printf "continue?"
System.Console.ReadLine()="y"
while doSomethingAndContinue() do ignore None
Although a bit more verbose, you can use recursive functions to avoid the "do while" as in :
let swap (a:int[]) i j =
let t = a.[i]
a.[i] <- a.[j]
a.[j] <- t
let rec bubbleSortAux a nMax j swapped =
if j >= 0 && j <= nMax then
if a.[j] > a.[j+1] then
swap a j (j+1)
bubbleSortAux a nMax (j+1) true
else
bubbleSortAux a nMax (j+1) false
else
swapped
let rec bubbleSortLoop a nMax =
if bubbleSortAux a nMax 0 false then
bubbleSortLoop a (nMax - 1)
let bubbleSort a =
bubbleSortLoop a (a.Length - 2)
let bubbleSort (a: _ []) =
let mutable fin = false
while not fin do
fin <- true
for i=0 to a.Length-2 do
if a.[i] > a.[i+1] then
let t = a.[i]
a.[i] <- a.[i+1]
a.[i+1] <- t
fin <- false
I do not know about F# very well, but F# is a functional language. Usually, there is no such thing as "for" or "while" loops in functional programming languages.
Functional languages define functions in a mathematical sense (like f(x) => ...). Writing a program comes down to defining and combining a set of mathematical functions. This means that the only way of coding loops is using recursion.
In Mathematics, there is no way of saying:
f(x) => "do 5 times this"
What you'd do is define f like:
count > 0 : f(x, count-1)
f(x, count) => {
count <= 0 : ...
And then use this function as in:
y = f(x, 5)
This would be exactly how you implement functions in functional languages.
At least, this is true for purely functional languages like Haskell...
You can do something like
let mutable ind = 0
while (
//Do your stuff here
//Now condition part return some boolean value
ind < 10
) do ind <- ind +1
I just recently found this way. It feels a bit hacky but what I like is that you can build something more complex what usually caused issues in C#, C++.
let mutable ind = 0
while (
(some condition) && (
//do something
let someValue = Eval ....
//Now more complex condition
ind + someValue < 10
)
) do ind <- ind +1