/
g
executable file
·87 lines (66 loc) · 1.83 KB
/
g
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/usr/bin/perl -w
use strict;
use sigtrap die => 'normal-signals';
use constant GOROOT => $ENV{GOROOT} || die "Missing GOROOT\n";
use constant GOARCH => $ENV{GOARCH} || die "Missing GOARCH\n";
use constant GOOS => $ENV{GOOS} || die "Missing GOOS\n";
use constant GO => {
arm => 5,
amd64 => 6,
386 => 8,
}->{(GOARCH)} || die "Unknown GOARCH";
use constant COMPILER => GO . 'g';
use constant LINKER => GO . 'l';
use constant EXE => GO. '.out';
use Fatal qw(open close);
if(@ARGV){ # like an interpreter
my($source) = shift @ARGV;
go_run($source, @ARGV);
}
else { # like a shell
my $libdir = sprintf '%s/pkg/%s_%s', GOROOT, GOOS, GOARCH;
-d $libdir or die "Missing go package directry ($libdir)\n";
require File::Find;
my @packages;
File::Find::find(sub{
return if !s/\.a \z//xms;
push @packages, $_;
}, $libdir);
my $packages_re = join('|', @packages);
my $go_file = "$$.go";
END{ unlink $go_file if defined $go_file }
$| = 1;
for(print "\n", "go> "; <STDIN>; print "\n", "go> "){
my @imports = $_ =~ /($packages_re)\./xmsg;
open my($out), '>', $go_file;
print $out go_main($_, @imports);
close $out;
go_run($go_file);
}
print "\n";
}
sub go_run{
my($source, @args) = @_;
# compile
system(COMPILER, $source) == 0 or return;
# link
(my $imd = $source) =~ s/\.go \z/'.' . GO/xmse;
system(LINKER, $imd) == 0 or return;
# exec
system('./' . EXE, @args) == 0 or return;
return;
}
sub go_main {
my($source, @imports) = @_;
my $import_directive = '';
if(@imports){
$import_directive = sprintf 'import(%s)', join ';', map{ qq{"$_"} } @imports;
}
return sprintf <<'__GO__', $import_directive, $source;
package main
%s
func main() {
%s;
}
__GO__
}