# 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) } } ```