Modulinos: Difference between revisions

From Rosetta Code
Content added Content deleted
(Simplified compilation process)
(Fixed LLVM)
Line 320: Line 320:


=={{header|LLVM}}==
=={{header|LLVM}}==
LLVM has scripted main by default.
LLVM can have scripted main a la C, using the weak attribute.


<lang sh>$ make
<lang llvm>@msg_directory = internal constant [15 x i8] c"Directory: %s\0A\00"
llvm-as scriptedmain.ll
@msg_program = internal constant [13 x i8] c"Program: %s\0A\00"
llc scriptedmain.bc
@msg_argc = internal constant [20 x i8] c"Number of Args: %d\0A\00"
gcc -o scriptedmain scriptedmain.s
@msg_arg = internal constant [10 x i8] c"Arg = %s\0A\00"
./scriptedmain
Main: The meaning of life is 42
llvm-as test.ll
llc test.bc
gcc -o test test.s scriptedmain.s
./test
Test: The meaning of life is 42</lang>


Makefile
declare i32 @printf(i8* noalias nocapture, ...)
declare i8* @getcwd(i8*, i32)


<lang make>EXECUTABLE_SM=scriptedmain
define i32 @main(i32 %argc, i8** %argv) {
EXECUTABLE_TEST=test
%cwd = alloca [1024 x i8]


all: test.ll scriptedmain.s
%cwd_ptr = getelementptr inbounds [1024 x i8]* %cwd, i32 0, i32 0
llvm-as test.ll
llc test.bc
gcc -o $(EXECUTABLE_TEST) test.s scriptedmain.s
./$(EXECUTABLE_TEST)


scriptedmain.s: scriptedmain.ll
call i8* @getcwd(i8* %cwd_ptr, i32 1024)
llvm-as scriptedmain.ll
llc scriptedmain.bc
gcc -o $(EXECUTABLE_SM) scriptedmain.s
./$(EXECUTABLE_SM)


clean:
call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @msg_directory, i32 0, i32 0), i8* %cwd_ptr)
rm $(EXECUTABLE_TEST)
rm $(EXECUTABLE_SM)
rm test.s
rm test.bc
rm scriptedmain.s
rm scriptedmain.bc</lang>


scriptedmain.ll
%program_ptr = getelementptr inbounds i8** %argv, i32 0


<lang llvm>@msg_main = internal constant [33 x i8] c"Main: The meaning of life is %d\0A\00"
%program = load i8** %program_ptr


declare i32 @printf(i8* noalias nocapture, ...)
call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @msg_program, i32 0, i32 0), i8* %program)


define i32 @meaning_of_life() {
call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([20 x i8]* @msg_argc, i32 0, i32 0), i32 %argc)
ret i32 42
}


define weak i32 @main(i32 %argc, i8** %argv) {
%i = alloca i32
%meaning = call i32 @meaning_of_life()
store i32 0, i32* %i
br label %for_args


call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([33 x i8]* @msg_main, i32 0, i32 0), i32 %meaning)
for_args:


%i_val = load i32* %i
ret i32 0
}</lang>


test.ll
%arg_ptr = getelementptr inbounds i8** %argv, i32 %i_val
%arg = load i8** %arg_ptr
call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @msg_arg, i32 0, i32 0), i8* %arg)


<lang llvm>@msg_test = internal constant [33 x i8] c"Test: The meaning of life is %d\0A\00"
%new_i_val = add i32 %i_val, 1
store i32 %new_i_val, i32* %i


declare i32 @printf(i8* noalias nocapture, ...)
%more_args = icmp slt i32 %new_i_val, %argc

br i1 %more_args, label %for_args, label %end_for_args
declare i32 @meaning_of_life()

define i32 @main(i32 %argc, i8** %argv) {
%meaning = call i32 @meaning_of_life()


call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([33 x i8]* @msg_test, i32 0, i32 0), i32 %meaning)
end_for_args:


ret i32 0
ret i32 0

Revision as of 00:15, 7 March 2011

Modulinos is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

It is useful to be able to execute a main() function only when a program is run directly. This is a central feature in programming scripts; the feature is called scripted main.

Examples from GitHub.

C

C programs cannot normally do scripted main, because main() is implicitly included by another program, test.c, even though scriptedmain.h omits any main() prototype. A compiler directive fixes this.

<lang sh>$ gcc -o scriptedmain scriptedmain.c scriptedmain.h $ ./scriptedmain Main: The meaning of life is 42 $ gcc -o test test.c scriptedmain.c scriptedmain.h $ ./test Test: The meaning of life is 42</lang>

scriptedmain.h

<lang c>int meaning_of_life();</lang>

scriptedmain.c

<lang c>#include <stdio.h>

int meaning_of_life() { return 42; }

int __attribute__((weak)) main(int argc, char **argv) { printf("Main: The meaning of life is %d\n", meaning_of_life());

return 0; }</lang>

test.c

<lang c>#include "scriptedmain.h"

  1. include <stdio.h>

extern int meaning_of_life();

int main(int argc, char **argv) { printf("Test: The meaning of life is %d\n", meaning_of_life()); return 0; }</lang>

C++

C++ programs cannot normally do scripted main, because main() is implicitly included by another program, test.c, even though scriptedmain.h omits any main() prototype. A compiler directive fixes this.

scriptedmain.h

<lang cpp>int meaning_of_life();</lang>

scriptedmain.cpp

<lang cpp>#include <iostream>

using namespace std;

int meaning_of_life() { return 42; }

int __attribute__((weak)) main(int argc, char **argv) { cout << "Main: The meaning of life is " << meaning_of_life() << endl;

return 0; }</lang>

test.cpp

<lang cpp>#include "scriptedmain.h"

  1. include <iostream>

using namespace std;

extern int meaning_of_life();

int main(int argc, char **argv) { cout << "Test: The meaning of life is " << meaning_of_life() << endl;

return 0; }</lang>

Chicken Scheme

Chicken Scheme has the {{{ -ss }}} flag for the interpreter, but compiled Chicken Scheme programs do not have scripted main unless the behavior is added manually to the code.

scriptedmain.scm

<lang scheme>#!/bin/bash

  1. |

exec csi -ss $0 ${1+"$@"} exit |#

(use posix) (require-extension srfi-1) ; lists

(define (meaning-of-life) 42)

(define (main args) (display (format "Main: The meaning of life is ~a\n" (meaning-of-life))) (exit))

(define (program) (if (string=? (car (argv)) "csi") (let ((s-index (list-index (lambda (x) (string-contains x "-s")) (argv)))) (if (number? s-index) (cons 'interpreted (list-ref (argv) (+ 1 s-index))) (cons 'unknown ""))) (cons 'compiled (car (argv)))))

(if (equal? (car (program)) 'compiled) (main (cdr (argv))))</lang>

test.scm

<lang scheme>#!/bin/bash

  1. |

exec csi -ss $0 ${1+"$@"} exit |# (define (main args) (load "scriptedmain.scm") (display (format "Test: The meaning of life is ~a\n" (meaning-of-life))) (exit))</lang>

Common Lisp

Common Lisp has few standards for POSIX operation. Shebangs and command line arguments are hacks.

In CLISP, this code only works for ./scriptedmain.lisp.

scriptedmain.lisp

<lang lisp>#!/bin/bash

  1. |

exec clisp -q -q $0 $0 ${1+"$@"} exit |#

Usage
./scriptedmain.lisp

(defun meaning-of-life () 42)

(defun main (args)

(format t "Main: The meaning of life is ~a~%" (meaning-of-life))
(quit))
With help from Francois-Rene Rideau
http://tinyurl.com/cli-args

(let ((args

      #+clisp ext:*args*
      #+sbcl sb-ext:*posix-argv*
      #+clozure (ccl::command-line-arguments)
      #+gcl si:*command-args*
      #+ecl (loop for i from 0 below (si:argc) collect (si:argv i))
      #+cmu extensions:*command-line-strings*
      #+allegro (sys:command-line-arguments)
      #+lispworks sys:*line-arguments-list*
    ))
 (if (member (pathname-name *load-truename*)
             args
             :test #'(lambda (x y) (search x y :test #'equalp)))
   (main args)))</lang>

test.lisp

<lang lisp>#!/bin/bash

  1. |

exec clisp -q -q $0 $0 ${1+"$@"} exit |#

(load "scriptedmain.lisp") (format t "Test: The meaning of life is ~a~%" (meaning-of-life))</lang>

Emacs Lisp

Emacs has scripted main, though older versions require an obscure shebang syntax.

scriptedmain.el

<lang lisp>:;exec emacs -batch -l $0 -f main $*

Shebang from John Swaby
http://www.emacswiki.org/emacs/EmacsScripts

(defun meaning-of-life () 42)

(defun main ()

(message "Main: The meaning of life is %d" (meaning-of-life)))</lang>

test.el

<lang lisp>:;exec emacs -batch -l $0 -f main $*

Shebang from John Swaby
http://www.emacswiki.org/emacs/EmacsScripts

(defun main ()

(setq load-path (cons default-directory load-path))
(load "scriptedmain.el" nil t)
(message "Test: The meaning of life is %d" (meaning-of-life)))</lang>

Erlang

Erlang has scripted main by default. scriptedmain.erl must be compiled before test.erl can access its functions.

scriptedmain.erl

<lang erlang>-module(scriptedmain). -export([meaning_of_life/0]). -import(lists, [map/2]).

meaning_of_life() -> 42.

main(_) -> io:format("Main: The meaning of life is ~w~n", [meaning_of_life()]).</lang>

test.erl

<lang erlang>% Compile scriptedmain.erl first.

-module(test). -import(scriptedmain, [meaning_of_life/0]).

main(_) -> io:format("Test: The meaning of life is ~w~n", [meaning_of_life()]).</lang>

Haskell

Haskell has scripted main, but getting scripted main to work with compiled scripts is tricky.

<lang sh>$ runhaskell scriptedmain.hs Main: The meaning of life is 42 $ runhaskell test.hs Test: The meaning of life is 42 $ ghc -fforce-recomp -o scriptedmain -main-is ScriptedMain scriptedmain.hs $ ./scriptedmain Main: The meaning of life is 42 $ ghc -fforce-recomp -o test -main-is Test test.hs scriptedmain.hs $ ./test Test: The meaning of life is 42</lang>

scriptedmain.hs

<lang haskell>#!/usr/bin/env runhaskell

-- Compile: -- -- ghc -fforce-recomp -o scriptedmain -main-is ScriptedMain scriptedmain.hs

module ScriptedMain where

meaningOfLife :: Int meaningOfLife = 42

main :: IO () main = putStrLn $ "Main: The meaning of life is " ++ show meaningOfLife</lang>

test.hs

<lang haskell>#!/usr/bin/env runhaskell

-- Compile: -- -- ghc -fforce-recomp -o test -main-is Test test.hs scriptedmain.hs

module Test where

import ScriptedMain hiding (main)

main :: IO () main = putStrLn $ "Test: The meaning of life is " ++ show meaningOfLife</lang>

J

Probably the simplest way to achive what I imagine "scripted main" to be, in J, involves the use of the Immex Phrase. Here, just before the script ends, you define the "main" which would take control if the script was used as a stand alone program.

Here is an example "scripted main" program, using this approach:

<lang j>NB. example "scripted main" code, saved as sm.ijs myName=: 'My name is George' 9!:29]1 9!:27'smoutput myName'</lang>

Here is an example consumer, which is another "scripted main" program:

<lang j>NB. example "alternate main" code require'sm.ijs' 9!:29]1 9!:27'smoutput length: ,":#myName'</lang>

Here is another example consumer. This example is library code, without any main:

<lang j>NB. example "non main" library code require'sm.ijs' 9!:29]0 reversed=:|.myName</lang>

Java

Java has scripted main by default.

ScriptedMain.java

<lang java>public class ScriptedMain { public static int meaningOfLife() { return 42; }

public static void main(String[] args) { System.out.println("Main: The meaning of life is " + meaningOfLife()); } }</lang>

Test.java

<lang java>public class Test { public static void main(String[] args) { System.out.println("Test: The meaning of life is " + ScriptedMain.meaningOfLife()); } }</lang>

LLVM

LLVM can have scripted main a la C, using the weak attribute.

<lang sh>$ make llvm-as scriptedmain.ll llc scriptedmain.bc gcc -o scriptedmain scriptedmain.s ./scriptedmain Main: The meaning of life is 42 llvm-as test.ll llc test.bc gcc -o test test.s scriptedmain.s ./test Test: The meaning of life is 42</lang>

Makefile

<lang make>EXECUTABLE_SM=scriptedmain EXECUTABLE_TEST=test

all: test.ll scriptedmain.s llvm-as test.ll llc test.bc gcc -o $(EXECUTABLE_TEST) test.s scriptedmain.s ./$(EXECUTABLE_TEST)

scriptedmain.s: scriptedmain.ll llvm-as scriptedmain.ll llc scriptedmain.bc gcc -o $(EXECUTABLE_SM) scriptedmain.s ./$(EXECUTABLE_SM)

clean: rm $(EXECUTABLE_TEST) rm $(EXECUTABLE_SM) rm test.s rm test.bc rm scriptedmain.s rm scriptedmain.bc</lang>

scriptedmain.ll

<lang llvm>@msg_main = internal constant [33 x i8] c"Main: The meaning of life is %d\0A\00"

declare i32 @printf(i8* noalias nocapture, ...)

define i32 @meaning_of_life() { ret i32 42 }

define weak i32 @main(i32 %argc, i8** %argv) { %meaning = call i32 @meaning_of_life()

call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([33 x i8]* @msg_main, i32 0, i32 0), i32 %meaning)

ret i32 0 }</lang>

test.ll

<lang llvm>@msg_test = internal constant [33 x i8] c"Test: The meaning of life is %d\0A\00"

declare i32 @printf(i8* noalias nocapture, ...)

declare i32 @meaning_of_life()

define i32 @main(i32 %argc, i8** %argv) { %meaning = call i32 @meaning_of_life()

call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([33 x i8]* @msg_test, i32 0, i32 0), i32 %meaning)

ret i32 0 }</lang>

Lua

Lua has scripted main by default, using an obscure syntax (an ellipsis of all things).

scriptedmain.lua

<lang lua>#!/usr/bin/env lua

function meaningoflife() return 42 end

function main(arg) print("Main: The meaning of life is " .. meaningoflife()) end

if type(package.loaded[(...)]) ~= "userdata" then main(arg) else module(..., package.seeall) end</lang>

test.lua

<lang lua>#!/usr/bin/env lua sm = require("scriptedmain") print("Test: The meaning of life is " .. sm.meaningoflife())</lang>

newLISP

newLISP lacks scripted main, but the feature is easily added.

scriptedmain.lsp

<lang lisp>#!/usr/bin/env newlisp

(context 'SM)

(define (SM:meaning-of-life) 42)

(define (main) (println (format "Main: The meaning of life is %d" (meaning-of-life))) (exit))

(if (find "scriptedmain" (main-args 1)) (main))

(context MAIN)</lang>

test.lsp

<lang lisp>#!/usr/bin/env newlisp

(load "scriptedmain.lsp") (println (format "Test: The meaning of life is %d" (SM:meaning-of-life))) (exit)</lang>

Octave/MATLAB

Octave and MATLAB have scripted main by default, because only the first function listed in a program are importable by other programs.

meaningoflife.m

<lang matlab>#!/usr/bin/env octave -qf

function y = meaningoflife() y = 42; endfunction

function main() printf("Main: The meaning of life is %d", meaningoflife()); endfunction

main();</lang>

test.m

<lang matlab>#!/usr/bin/env octave -qf

printf("Test: The meaning of life is %d", meaningoflife());</lang>

Perl

Perl has scripted main.

scriptedmain.pm

<lang perl>#!/usr/bin/env perl

use strict;

sub meaning_of_life { return 42; }

sub main { print "Main: The meaning of life is " . meaning_of_life() . "\n"; }

unless(caller) { main; }</lang>

test.pl

<lang perl>#!/usr/bin/env perl

use strict; use ScriptedMain;

print "Test: The meaning of life is " . meaning_of_life() . "\n";</lang>

PHP

PHP does not have scripted main, but the feature is easily added with a regular expression.

scriptedmain.php

<lang php><?php function meaning_of_life() { return 42; }

function main($args) { echo "Main: The meaning of life is " . meaning_of_life() . "\n"; }

if (preg_match("/scriptedmain/", $_SERVER["SCRIPT_NAME"])) { main($argv); } ?></lang>

test.php

<lang php><?php require_once("scriptedmain.php"); echo "Test: The meaning of life is " . meaning_of_life() . "\n"; ?></lang>

Python

Python has scripted main.

scriptedmain.py

<lang python>#!/usr/bin/env python

def meaning_of_life(): return 42

def main(): print "Main: The meaning of life is %s" % meaning_of_life()

if __name__=="__main__": main()</lang>

test.py

<lang python>#!/usr/bin/env python

import scriptedmain

print "Test: The meaning of life is %s" % scriptedmain.meaning_of_life()</lang>

R

R does not have scripted main, but the feature is easily added with regular expressions.

scriptedmain.R

<lang R>#!/usr/bin/Rscript

meaningOfLife <- function() { 42 }

main <- function(program, args) { cat("Main: The meaning of life is", meaningOfLife(), "\n") }

getProgram <- function(args) { sub("--file=", "", args[grep("--file=", args)]) }

args <- commandArgs(trailingOnly = FALSE) program <- getProgram(args)

if (length(program) > 0 && length(grep("scriptedmain", program)) > 0) { main(program, args) q("no") }</lang>

test.R

<lang R>#!/usr/bin/Rscript

source("scriptedmain.R")

cat("Test: The meaning of life is", meaningOfLife(), "\n")

q("no")</lang>

Ruby

Ruby has scripted main.

scriptedmain.rb

<lang ruby>#!/usr/bin/env ruby

def meaning_of_life 42 end

def main puts "Main: The meaning of life is #{meaning_of_life}" end

if __FILE__ == $0 main end</lang>

test.rb

<lang ruby>#!/usr/bin/env ruby

require "scriptedmain"

puts "Test: The meaning of life is #{meaning_of_life}"</lang>

Tcl

<lang tcl>proc main {args} {

   puts "Directory: [pwd]"
   puts "Program: $::argv0"
   puts "Number of args: [llength $args]"
   foreach arg $args {puts "Arg: $arg"}

}

if {$::argv0 eq [info script]} {

   main {*}$::argv

}</lang>

UNIX Shell

Bash has scripted main.

scriptedmain.sh

<lang sh>#!/usr/bin/env sh

meaning_of_life() { return 42 }

main() { meaning_of_life echo "Main: The meaning of life is $?" }

if "$BASH_SOURCE" == "$0" then

   main

fi</lang>

test.sh

<lang sh>#!/usr/bin/env sh source scriptedmain.sh meaning_of_life echo "Test: The meaning of life is $?"</lang>