Is it possible to compile a string of coffeescript with the npm module, I have been looking everywhere and cannot seem to find any good answers.
The coffee-script module provides a "compile" method:
var cs = require('coffee-script');
var js = cs.compile('foo = -> "bar"');
If you're talking about the coffee command line utility, then yes you can (although it isn't too pretty):
echo "alert 'Hello World'" | coffee -sc
The code above compiles the CoffeeScript in the echo and outputs to STDOUT. If you want the compiled output in a file, you can do this:
echo "alert 'Hello World'" | coffee -sc > path/to/file.js
There's some good documentation on the command-line utility here: http://coffeescript.org/#usage
If you mean compiling a string within CoffeeScript code, the coffee-script module provides a compile function:
coffee = require 'coffee-script'
js = coffee.compile "alert 'Hello World'"
Related
Windows 7 x64, Erlang-OTP 17.
I wrote simple module like this:
-module (somequery).
-export ([fbquery/2]).
fbquery(P1,P2) ->
inets:start(),
ssl:start(),
token = "78a8shd67tyajsndweiu03hr83h19j",
Encoded = {"Authorization","Basic " ++ base64:encode_to_string(lists:append([token,":",""]))},
ContentType = "application/xml",
Headers = [Encoded, {"Content-Type",ContentType}],
Options = [{body_format,binary}],
{ok, File}=file:read_file(P1),
Res = httpc:request(post, {"https://datapi.com/api/xml4-8", Headers, ContentType, File}, [], Options),
file:write_file(P2, io_lib:fwrite("~p.\n", [Res])).
This code working in interactive mode (werl.exe), and compiling into beam.
The question is how use *.erl or compiled *.beam module now? How import it and run fbquery/2 method?
First of, you need to add the directory containing your beam with the argument -pa Dir1 Dir2 .... It will add the directory to the erlang path and you will be able to type somequery:fbquery(Arg1,Arg2) in your shell.
Then, you can use the argument -s module function [args..] to launch erl with the specified function.
You can read about it in the erlang documentation for erl.
I started learning Ada recently and knowing that Ada and C object files can be linked together to build a multilingual program or library, is it possible to call Ada code from Perl using XS?
Yes!
In fact, any language that can be called from C can be used from Perl using XS. Here's a solution to how to do it with an Ada module and ExtUtils::MakeMaker.
Setting things up
Module tree
Let's start by creating a module tree using h2xs:
$ h2xs -A -n MyAdaModule
Then let's create a subdirectory to hold our Ada files:
$ cd MyAdaModule
$ mkdir src
Here is the module's specification: src/hello.ads
procedure hello;
... and the body: src/hello.adb
with Ada.Text_IO;
use Ada.Text_IO;
procedure hello is
begin
Put_Line("Hi from Ada!");
end;
Don't forget to update the MANIFEST.
Writing the XS file
Let's write the body of MyAdaModule.xs now. It's pretty much like using a function from a C library:
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
extern void adainit();
extern void adafinal();
MODULE = MyAdaModule PACKAGE = MyAdaModule
void say_hello()
CODE:
adainit();
hello();
adafinal();
From the gnat documentation we know that we need to call adainit() and adafinal() to initialise and then clean up. These calls surround hello() here but they would probably be in a better place in some other function in your XS file. They would then be called from a BEGIN and END block in your Perl module.
Time to compile!
Ada library
First, we don't want to delegate all the magic linking and binding to MakeMaker so let's create a makefile in the src/ directory that will compile our Ada code into a static library.
To make this library, hello.a, we just have to follow the gnat documentation:
use gnatmake -c to generate a hello.ali and a hello.o;
use hello.ali with gnatbind with the -n switch. This will generate b~hello.adb and b~hello.ads which contain binding code;
compile b~hello.adb into an object file: b~hello.o.
group hello.o and b~hello.o together into an archive with ar
So, in short, we will use this makefile:
all: hello.a
hello.a: hello.o b~hello.o
ar rcs $# $^
hello.o: hello.adb hello.ads
gnatmake -c -o $# $<
b~hello.o: b~hello.adb b~hello.ads
gnatmake -c -o $# $<
b~hello.adb: hello.ali
gnatbind -n $<
hello.ali: hello.o
clean:
rm -rf *.o *.ali *.a b~*
Don't forget to update the MANIFEST.
Makefile.PL
Finally, the MakeFile.PL file needs some editing. It has to call the above makefile to build our library and then use it in the final linking phase. This is done by setting MYEXTLIB to src/hello.a and by adding a rule in the postamble section.
In our case, we also need to link with libgnat (for Ada.Text_IO) which should reside somewhere on your system. This is done by editing LIBS. In this example the path is hardcoded but you should probably figure out a more portable way to find libgnat.
use 5.018001;
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
NAME => 'MyAdaModule',
VERSION_FROM => 'lib/MyAdaModule.pm', # finds $VERSION
PREREQ_PM => {}, # e.g., Module::Name => 1.1
($] >= 5.005 ? # Add these new keywords supported since 5.005
(ABSTRACT_FROM => 'lib/MyAdaModule.pm', # retrieve abstract from module
AUTHOR => 'A. U. Thor <author#nonet>') : ()),
DEFINE => '', # e.g., '-DHAVE_SOMETHING'
INC => '-I.', # e.g., '-I. -I/usr/include/other'
LIBS => ['-L/usr/lib/gcc/i686-pc-linux-gnu/4.8.2/adalib/ -lgnat'],
MYEXTLIB => 'src/hello.a',
);
sub MY::postamble {
join("\n",
"\$(MYEXTLIB)::",
"\tmake -C src/",
"",
"clean::",
"\tmake -C src/ clean",
);
}
Now try
$ perl Makefile.PL
$ make
$ make test
And surprise: the test doesn't pass! The hello() symbol doesn't exist. Inspecting the MyAdaLib.so generated by make with the nm tool reveals that some symbols have been renamed. In my case, they were prefixed with _ada_. So I'd have to call _ada_hello() instead of hello(). This can be corrected in src/ada.ads using the Export pragma:
pragma Export
(Convention => C,
Entity => hello,
External_Name => "hello" );
From what I understood, this should be done for all public symbols as it ensures the representation of types, records, etc, is understood from a C program.
Now, you should be able to call hello() from the XSUB. Enjoy!
I have a main coffee file and a mix of other coffee and livescript files.
# main.coffee
require 'LiveScript'
one = require './one.coffee'
two = require './two.ls'
console.log one.fun(), two.fun()
# one.coffee
module.exports.fun = -> 1
# two.ls
module.exports.fun = -> 2
I can run
coffee main.coffee
But trying to run
browserify -t coffeeify main.coffee
Gives an error:
module.exports.fun = -> 2
^
ParseError: Unexpected token >
The only workaround I see is to compile ls files to js first. Is there a simpler, direct way to mix ls and coffee files?
require 'LiveScript' is only sufficient for Node.js. Browserify does not support require.extensions, and is trying to parse the LiveScript as JavaScript.
You need a transform for LiveScript as well, for example Liveify.
You might try Webpack. With proper loaders, e.g. livescript-loader, coffee-loader and others, you can compose your program with different js flavors.
I would like to make a Cakefile task to watch some CoffeeScript files just like if I had run coffee -c -w js/*.coffee.
Its watching and recompiling them successfully, but it doesn't log the usual output to the terminal when there's a compile error like it would if I just ran the script from the terminal. Any idea how to make this happen?
exec = require('child_process').exec
task 'watch','watch all files and compile them as needed', (options) ->
exec 'coffee -c -w js/*.coffee', (err,stdout, stderr) ->
console.log stdout
Also, if there's a better way to invoke a coffeescript command from a cakefile than running 'exec' please post that too.
spawn instead of exec?
{spawn} = require 'child_process'
task 'watch', -> spawn 'coffee', ['-cw', 'js'], customFds: [0..2]
I've used spawn to solve this, here is an example cake file:
{spawn, exec} = require 'child_process'
option '-p', '--prefix [DIR]', 'set the installation prefix for `cake install`'
task 'build', 'continually build with --watch', ->
coffee = spawn 'coffee', ['-cw', '-o', 'lib', 'src']
coffee.stdout.on 'data', (data) -> console.log data.toString().trim()
You can see it in action with the docco project:
https://github.com/jashkenas/docco/blob/master/Cakefile
The problem with your original code was that exec only calls its callback once—after the child process has terminated. (The Node docs aren't so clear on this.) So instead of defining that callback, you should instead try
child = exec 'coffee -c -w js/*.coffee'
child.stdout.on 'data', (data) -> sys.print data
Let me know if that works for you.
I've got c++ code that needs a sed done to it prior to compilation. How do I place this into Makefile.am?
I tried the typical makefile setup and the target appears to not exist:
gentest.cc:
$(SED) -i "s|FIND|REPLACE|" gentest.cc
If you are interested as to why I want to do this, it's because I wrote my program (slider3.py) in python and my partner wrote his in c++ (gentest.cc) and his needs to call mine. I'm accomplishing this by editing the argv and then using execv().
... {
char **argv2 = new char*[argc];
memset(argv2,0,sizeof(argv2));
argv2[0] = "__PREFIX__/bin/slider3.py";
memcpy(argv2 + 1, argv + 2, sizeof(char *) * (argc - 2));
int oranges = execv(argv2[0], argv2);
printf("%s\n", strerror(oranges));
return oranges;
} ...
I've already handled getting the #! added to slider3.py and chmod +x by using the method that was not working for gentest.cc. I've also handled adding slider3.py to the list of files that get installed.
EXTRA_DIST=testite.sh slider3_base.py
bin_SCRIPTS = slider3.py
CLEANFILES = $(bin_SCRIPTS)
slider3.py: slider3_base.py
rm -f slider3.py
echo "#! " $(PYTHON) > slider3.py
cat slider3_base.py >> slider3.py
chmod +x slider3.py
gentest is defined this way in Makefile.am:
bin_PROGRAMS = gentest
gentest_SOURCES = gentest.cc
gentest_LDADD = libgen.a #../libsbsat.la $(LIBM)
And this fails to be run during make (note the # pattern is successfully expanded in Makefile):
gentest.cc:
$(SED) -i "s|__PREFIX__|#prefix#|" gentest.cc
Any ideas on how to get sed to run before compiling gentest.cc?
Don't use in-place sed.
Instead:
gentest_SOURCES = gentest-seded.cc
gentest-seded.cc : gentest.cc
$(SED) "s|__PREFIX__|#prefix#|" $< >$#
Have you ever considered #define-ing it in config.h (you're using autotools, right?) or passing it using -D when compiling? This is really not the case for sed.
The details from Andrew Y's answer:
in your C++ source, specify:
argv2[0] = SCRIPTPREFIX "/bin/slider3.py";
then compile with
-DSCRIPTPREFIX='"/your/script/prefix"'
Have you considered calling the Python code directly from the C++? Here is a tutorial on using boost to call python functions from C++. The method you are describing here seems very brittle.