# Weekend Project
## Go by Example
### Image Downloader
* [Go by example](https://golangbyexample.com/download-image-file-url-golang/)
* dlv debug with command line argument
* `dlv debug -- https://yourbasic.org/golang/directions.jpg -o logo.png`
* Use `--` to separate (flag) args to dlv itself from args to the debugged binary.
### URL Parsing
* [Go by example](https://gobyexample.com/url-parsing)
>`sandbox/go/weekend_project/url-parsing/`
* :question: What section does URL contain?
* [IBM - The components of a URL](https://www.ibm.com/support/knowledgecenter/SSGMCP_5.2.0/com.ibm.cics.ts.internet.doc/topics/dfhtl_uricomp.html)
* `scheme://host:port/path?query`
* scheme:
* e.g.
* http (without ssl)
* https (with ssl)
* host
* e.g.
* www.google.com
* port
* e.g.
* `80`
* file path
* `/software/htp/cics/index.html`
* query string
* seperate by `&`
* e.g.
* `term=bluebird&source=browser-search`
### Go's URL structure:
* [go url package](https://golang.org/pkg/net/url/#URL)
The general form represented is:
```
[scheme:][//[userinfo@]host][/]path[?query][#fragment]
```
URLs that do not start with a slash after the scheme are interpreted as:
```
scheme:opaque[?query][#fragment]
```
```go=
type URL struct {
Scheme string
Opaque string // encoded opaque data
User *Userinfo // username and password information
Host string // host or host:port
Path string // path (relative paths may omit leading slash)
RawPath string // encoded path hint (see EscapedPath method); added in Go 1.5
ForceQuery bool // append a query ('?') even if RawQuery is empty; added in Go 1.7
RawQuery string // encoded query values, without '?'
Fragment string // fragment for references, without '#'
RawFragment string // encoded fragment hint (see EscapedFragment method); added in Go 1.15
}
```
### Flag package in go - stringparse
* [Building a Simple CLI Tool with Golang
](https://blog.rapid7.com/2016/08/04/build-a-simple-cli-tool-with-golang/)
### What is Flags in golang's definition?
* In the context of its flag package,
* all strings beginning with dashes (single or double) are considered flags,
* e.g. `-p`
* and all strings without dashes that are not user input are considered arguments.
* All strings after the first argument are considered arguments.
### Go by Example: Command-Line Flags
* :question: What does `flag.String()` do?
:::spoiler
```shell
func String(name string, value string, usage string) *string
String defines a string flag with specified name, default value, and usage
string. The return value is the address of a string variable that stores the
value of the flag.
```
:::
* Positional argument:
* all flags need to appear before positional arguments
* 因為 go 用的不是 `gnu style` flag
* 要使用 `gnu style flag`:
* 請用 [spf13 / pflag package](github.com/spf13/pflag)
* e.g.
* `./command-line-flags -word=opt a1 a2 a3 -numb=7`
* output:
```shell
word: opt
numb: 42
fork: false
svar: bar
tail: [a1 a2 a3 -numb=7]
```
* :question: What does `flag.StringVar()` do ?
* It can pass the value from the flag to internal variable of program
### Go by Example: Command-Line Subcommands
* [Go by Example: Command-Line Subcommands](https://gobyexample.com/command-line-subcommands)
* :question: What is subcommand?
* e.g. `docker run -p 80:8080`
* `docker` is a command
* `run` is a subcommand
* `-p` is a flag for subcommand `run`
## Parser
### [Building a JSON Parser and Query Tool with Go](https://medium.com/@bradford_hamilton/building-a-json-parser-and-query-tool-with-go-8790beee239a)
### [Math parser in go](https://www.mathparsers.com/math-parser-for-go/)
### 9cc Compiler
[創造計算機等級的語言](https://koshizuow.gitbook.io/compilerbook/calculator_level_language)
:::success
* Finished:
* Makefile
* test.sh
* 9cc.c
TODO: [第2步:製作可以算加減法的編譯器](https://koshizuow.gitbook.io/compilerbook/calculator_level_language/step2)
:::
* :question: Return value of function 通常存在哪裡?
* ans: rax register
* Quote:把回傳值放進 RAX 是一般的共識
* ref: [簡單的範例](https://koshizuow.gitbook.io/compilerbook/machine_code_assembler/c_assembly/kantan_na_rei)
* :question: How to implement addition?
* :question: `strtol(p, &p, 10)` 在 p 指向 digit 的行為是?
* e.g. `5 + 20 + 4`, p point to addr of 4
* 會把 p 指向的 digit character 轉換成 long int 並 return,
* 並把 4 之後的 `\0` 的 addr assign 給 `p`
* 行為就像是 `p = p + 1` 一樣
* ref: man page of strtol
### Calculator
* Ref
* [rezroo/Dockerfile](https://gist.github.com/rezroo/da8c7c6169dc61da786e3ede78261854)
### Code
```go=1
package main
import (
"errors"
"fmt"
"os"
"strconv"
)
func calculate(e []string) (float64, error) {
result := 0.0
num1, err := strconv.ParseFloat(e[0], 64)
if err != nil {
return 0.0, err
}
num2, err := strconv.ParseFloat(e[2], 64)
if err != nil {
return 0.0, err
}
switch e[1] {
case "*":
result = num1 * num2
case "/":
if num2 == 0.0 {
return 0.0, errors.New("error: you tried to divide by zero.")
}
result = num1 / num2
case "+":
result = num1 + num2
case "-":
result = num1 - num2
default:
return 0.0, errors.New("error: don't know how to do that")
}
return result, nil
}
func main() {
if len(os.Args) != 4 {
fmt.Println("error: wrong number of arguments")
return
}
res, err := calculate(os.Args[1:])
if err != nil {
fmt.Println(err)
} else {
fmt.Println(res)
}
}
```