-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
main.go
108 lines (93 loc) · 1.94 KB
/
main.go
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// This is the main-driver for our compiler.
package main
import (
"bytes"
"flag"
"fmt"
"os"
"os/exec"
"github.com/skx/math-compiler/compiler"
)
func main() {
//
// Look for flags.
//
debug := flag.Bool("debug", false, "Insert debug \"stuff\" in our generated output.")
compile := flag.Bool("compile", false, "Compile the program, via invoking gcc.")
program := flag.String("filename", "a.out", "The program to write to.")
run := flag.Bool("run", false, "Run the binary, post-compile.")
flag.Parse()
//
// If we're running we're also compiling
//
if *run {
*compile = true
}
//
// Ensure we have an expression as our single argument.
//
if len(flag.Args()) != 1 {
fmt.Printf("Usage: math-compiler 'expression'\n")
os.Exit(1)
}
//
// Create a compiler-object, with the program as input.
//
comp := compiler.New(flag.Args()[0])
//
// Are we inserting debugging "stuff" ?
//
if *debug {
comp.SetDebug(true)
}
//
// Compile
//
out, err := comp.Compile()
if err != nil {
fmt.Printf("Error compiling: %s\n", err.Error())
os.Exit(1)
}
//
// If we're not compiling the assembly language text which was
// produced then we just write the program to STDOUT, and terminate.
//
if !*compile {
fmt.Printf("%s", out)
return
}
//
// OK we're compiling the program, via gcc.
//
gcc := exec.Command("gcc", "-static", "-o", *program, "-x", "assembler", "-")
gcc.Stdout = os.Stdout
gcc.Stderr = os.Stderr
//
// We'll pipe our generated-program to STDIN of gcc, via a
// temporary buffer-object.
//
var b bytes.Buffer
b.Write([]byte(out))
gcc.Stdin = &b
//
// Run gcc.
//
err = gcc.Run()
if err != nil {
fmt.Printf("Error launching gcc: %s\n", err)
os.Exit(1)
}
//
// Running the binary too?
//
if *run {
exe := exec.Command(*program)
exe.Stdout = os.Stdout
exe.Stderr = os.Stderr
err = exe.Run()
if err != nil {
fmt.Printf("Error launching %s: %s\n", *program, err)
os.Exit(1)
}
}
}