Run arbitrary code at compile time - compile-time

I know that Crystal has its macro system for defining code at compile time but is it possible to run code apart from that?
For example, can we do this so that it runs during compilation?
puts "foobar"
Or for a more serious example, can we read from and write to the file system where the compiler is running?

Yes we can! With the help of the run macro method or the system macro method.
Let's have an example that compiles a random greeting into the program each time it is build:
greetings.txt:
Hello
Hey
Hi
greeting.cr:
puts File.read_lines("#{__DIR__}/greetings.txt").sample
greeter.cr:
puts {{run("./greeting").stringify}}
Compile with crystal build greeter.cr, you'll notice that the output stays the same for the compiled binary but is random for each time your recompile it.

As an additional answer to what Jonne said, you can output something at compile time using puts, but inside a macro. For example:
{{ puts "foobar" }}
You'll notice that "foobar" is printed during compilation but the executable does nothing (try it with crystal build foo.cr; ./foo)
Of course just outputting something at compile time isn't very useful, but it's useful when you want to debug some macros in a quick way.
The puts macro method is documented here: http://crystal-lang.org/api/Macros.html#puts%28expression%29%3ANop-instance-method

Related

Detect Whether Script Was Imported or Executed in Lua

In python, there is a common construction of the form if __name__ == "__main__": to detect whether the file was imported or executed directly. Usually, the only action taken in this conditional is to execute some "sensible, top level" function. This allows the same file to be used as a basic script and as a library module (and also as something an interactive user can import and use).
I was wondering if there is a clean and reliable way to do this in lua. I thought I could use the _REQUIREDNAME global variable, but it turns out that this was changed in Lua 5.1. Currently, the lua require passes arguments (in the variadic ...), so in principle, these can be examined. However, this is either not reliable, not clean, or probably both, because obviously when a script is executed arguments can be passed. So to do this safely, you would have to examine the arguments.
FWIW, require passes the module name as argument 1 (the string you called require on), and the path to the file it eventually found as argument 2. So there is a obviously some examination that can be done to try to detect this, which if not nearly as nice as if __name__ == "__main__": and can always be bypassed by a user by passing two suitably constructed arguments to the script. Not exactly a security threat, but I would hope there is a better solution.
I also experimented with another method, which I found very ugly but promising. This was to use debug.traceack(). If the script is executed directly, the traceback is very predictable, in fact, it only has 3 lines. I thought this might be it, although, like I said, an ugly hack for sure.
Do any more frequent lua users have advice? In effect, if I am writing module X, I want to either return X.main_func() in script mode or return X in import mode.
EDIT:
I took out an item which was actually incorrect (and makes my traceback solution workable). Additionally, the link provided in the comment by Egor Skriptunoff did provide another trick from the debug library which is even cleaner than using the traceback. Other than that, it seems that everyone ran into the same issues as me and the lua team has been disinterested in providing an official means to support this.
Based on the links provided by Egor, the current cleanest and safest way to do this seems to be as outlined here:
How to determine whether my code is running in a lua module?
which I repeat for ease of reference:
if pcall(debug.getlocal, 4, 1) then
print("in package")
else
print("in main script")
end
There is a whole thread about it here:
http://lua.2524044.n2.nabble.com/Modules-with-standalone-main-program-td7681497.html
Like I said, it seems this is a popular feature which is going to remain unsupported for the time being, but the debug.getlocal method seems to be what common lua developers have settled on for now.
A require() returning in package.loaded.
So simply check package.loaded for what you want.
Also as a good start for more experience in that methodic i suggest to write package.preload functions for require() stuff without manipulating the path.
A simple example for showing this...
# /usr/local/bin/lua -i
Lua 5.4.3 Copyright (C) 1994-2021 Lua.org, PUC-Rio
> package.preload.mymod=function() return {dump=function(...)
>> local args={...}
>> local test,dump=pcall(assert,args[1])
>> if test then
>> for key,value in pairs(dump) do
>> io.write(string.format("%s=%s\n",key,value)):flush()
>> end
>> return true
>> else
>> return test,dump
>> end
>> end} end
> mymod=require('mymod')
> mymod.dump(package.loaded)
string=table: 0x56693590
mymod=table: 0x566aa890
utf8=table: 0x56694d80
package=table: 0x56691ed0
math=table: 0x56693cb0
table=table: 0x566920d0
_G=table: 0x56690730
debug=table: 0x566950e0
coroutine=table: 0x56692310
os=table: 0x56692e60
io=table: 0x566921b0
true

Basic Erlang module troubles

So I straight up copy and pasted the code from the Erlang docs: https://erlang.org/doc/reference_manual/modules.html#module-syntax
Please help!
The module didn't compiled. To fix it try this in the Erlang shell (eshell):
1> c(m).
ok
2> m:fact(1).
1
See documentation on how code loading works.
exception error: undefined shell command
almost always means that the shell environment does not have the intended function, which can also mean that the module which contains its definition has not been loaded for all the code that we write by our hand and execute. You can deliberately try to misspell some auto loaded BIF(s) for example "length1" and you will still see same message showing up.

Source env variables from bitbake-made sdk using Fish

When you compile a SDK using bitbake and have to source like :
source /opt/poky/.../environment-setup-cortexa9hf-vfp-neon-poky-linux-gnueabi
It can't be accomplished through fish, which is expected as the export sintaxe is different (i.e. set -x ...). I tried even to add #!/bin/bash on the first line, which also doesn't work. Does anyone knows a good way for it?
Workaround: Nowadays I run a bash inside the fish prompt to be able to compile binaries, which is not the best way but works. Don't let those small things push oyu away from fish :)
#charego mentioned some good ideas, thanks! :)
Fish-bax
So you can run it as:
bax 'source /opt/poky/.../environment-setup-cortexa9hf-vfp-neon-poky-linux-gnueabi'
The only down side is that the auto completion does not work inside quotes, so one will need to write the whole path to the file. Although it's still better to have a fish running on top of a bash.
Bass
Bass did not worked, as it crashs with: Fatal Python error: Py_Initialize: Unable to get the locale encoding ImportError: No module named 'encodings'
Foreign-env
Foreign-env also didn't work. It's possible to to set the variable, although it threw warning:
warning: include location "/usr/local/include" is unsafe for cross-compilation [-Wpoison-system-directories]
and it does not compiles, probably it misses a few variables to export.
TL;DR Go with Fish-bax, at least it works :)

What is the syntax to comment a line in a tibco ems script

In a script which looks like below
create queue one
create queue two
create topic three
How can I comment a line?
I could find noting in either the tool itself or documentation.
The closest thing to comments you could do is:
echo off some comments here
tibemsadmin does not fail, and don't react to extra parameters. The "echo" command is harmless... so it is a great candidate.
Of course, you might prefer "echo on".
Not a great solution, but the only one I find.
Are you referring to the script that will be executed by tibemsadmin binary? You can try to prepend "#" in the front of the line which you don't need.
There is no way to run a command against the EMS server that is a comment. The easiest is to let it crash.
I've use
// Comment line "Creating queue for XYZ process"
However it still generates an error which wasn't a problem until we have just implemented continuous deployments for EMS and Tibco BW Ears, and it stopped when there was an error coming back from the command.
You could write a quick pre-processor that reads each line of the EMS script file and spits out a separate file that you can just run without errors. I'd do something like
(Your language of choice)
for each line in the file
if line starts with // then
do nothing
else
write it to the other file
end loop

statically analysing Lua code for potential errors

I'm using a closed-source application that loads Lua scripts and allows some customization through modifying these scripts. Unfortunately that application is not very good at generating useful log output (all I get is 'script failed') if something goes wrong in one of the Lua scripts.
I realize that dynamic languages are pretty much resistant to static code analysis in the way C++ code can be analyzed for example.
I was hoping though, there would be a tool that runs through a Lua script and e.g. warns about variables that have not been defined in the context of a particular script.
Essentially what I'm looking for is a tool that for a script:
local a
print b
would output:
warning: script.lua(1): local 'a' is not used'
warning: script.lua(2): 'b' may not be defined'
It can only really be warnings for most things but that would still be useful! Does such a tool exist? Or maybe a Lua IDE with a feature like that build in?
Thanks, Chris
Automated static code analysis for Lua is not an easy task in general. However, for a limited set of practical problems it is quite doable.
Quick googling for "lua lint" yields these two tools: lua-checker and Lua lint.
You may want to roll your own tool for your specific needs however.
Metalua is one of the most powerful tools for static Lua code analysis. For example, please see metalint, the tool for global variable usage analysis.
Please do not hesitate to post your question on Metalua mailing list. People there are usually very helpful.
There is also lua-inspect, which is based on metalua that was already mentioned. I've integrated it into ZeroBrane Studio IDE, which generates an output very similar to what you'd expect. See this SO answer for details: https://stackoverflow.com/a/11789348/1442917.
For checking globals, see this lua-l posting. Checking locals is harder.
You need to find a parser for lua (should be available as open source) and use it to parse the script into a proper AST tree. Use that tree and a simple variable visibility tracker to find out when a variable is or isn't defined.
Usually the scoping rules are simple:
start with the top AST node and an empty scope
item look at the child statements for that node. Every variable declaration should be added in the current scope.
if a new scope is starting (for example via a { operator) create a new variable scope inheriting the variables in the current scope).
when a scope is ending (for example via } ) remove the current child variable scope and return to the parent.
Iterate carefully.
This will provide you with what variables are visible where inside the AST. You can use this information and if you also inspect the expressions AST nodes (read/write of variables) you can find out your information.
I just started using luacheck and it is excellent!
The first release was from 2015.

Resources