Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dsl-vs-sdf #1296

Merged
merged 1 commit into from Jun 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 5 additions & 2 deletions README.md
Expand Up @@ -32,17 +32,19 @@ The Go+ programming language is designed for engineering, STEM education, and da

For more details, see [Quick Start](doc/docs.md).


## Key Features of Go+

* A static typed language.
* The simplest engineering language that can be mastered by children (script-like style).
* Performance: as fast as Go (Go+'s main backend compiles to human-readable Go).
* Fully compatible with [Go](https://github.com/golang/go) and can mix Go/Go+ code in the same package (see [Go/Go+ hybrid programming](doc/docs.md#gogo-hybrid-programming)).
* No DSL (Domain Specific Language) support, but Specific Domain Friendly (see [DSL vs. SDF](doc/dsl-vs-sdf.md)).
* REPL: see [iGo+](https://github.com/goplus/igop).
* No DSL (Domain Specific Language) support, but it's Specific Domain Friendly (see [DSL vs. SDF](doc/dsl-vs-sdf.md)).
* Support Go code generation (main backend) and bytecode backend (REPL: see [iGo+](https://github.com/goplus/igop)).
* [Simplest way to interaction with C](doc/docs.md#calling-c-from-go) (cgo is supported but not recommended).
* [Powerful built-in data processing capabilities](doc/docs.md#data-processing).


## How to install

### from source code
Expand All @@ -67,6 +69,7 @@ all.bat
brew install goplus
```


## Go+ Applications

### 2D Games powered by Go+
Expand Down
169 changes: 169 additions & 0 deletions doc/dsl-vs-sdf.md
Expand Up @@ -3,4 +3,173 @@ Go+ ClassFile: DSL vs. SDF

Go+ doesn't support DSL (Domain Specific Language), but it's SDF (Specific Domain Friendly).

The Go+ philosophy of Domain is:

```
Don't define a language for specific domain.
Abstract domain knowledge for it.
```

Go+ introduces `ClassFile` to abstract domain knowledge.

NOTE: `ClassFile` is still in beta and may be subject to change.

What is `ClassFile`?

TODO


## DEMO: Go+ DevOps Tools

This is a demo project to implement a new `ClassFile` work: [github.com/xushiwei/gsh](https://github.com/xushiwei/gsh).

Before we dive into implementation of `github.com/xushiwei/gsh`, let's take a look how to use it.

First, let's create a new module named [gshexample](https://github.com/xushiwei/gshexample):

```sh
mkdir gshexample
cd gshexample
gop mod init gshexample
```

Second, get `github.com/xushiwei/gsh` into `gshexample`:

```sh
gop get github.com/xushiwei/gsh
```

Third, create a Go+ source file named `./example.gsh` and write the following code:

```coffee
mkdir "testgsh"
```

Fourth, run this project:

```sh
gop mod tidy
gop run .
```

It's strange to you that the file extension of Go+ source is not `.gop` but `.gsh`.

But the Go+ compiler can recognize `.gsh` files as Go+ source because `github.com/xushiwei/gsh` register `.gsh` as its `ClassFile` file extension.

We can change `./example.gsh` more complicated:

```coffee
type file struct {
name string
fsize int
}

mkdir! "testgsh"

mkdir "testgsh2"
lastErr!

mkdir "testgsh3"
if lastErr != nil {
panic lastErr
}

capout => { ls }
println output.fields

capout => { ls "-l" }
files := [file{flds[8], flds[4].int!} for e <- output.split("\n") if flds := e.fields; flds.len > 2]
println files

rmdir "testgsh", "testgsh2", "testgsh3"
```

### Check last error

If we want to ensure `mkdir` successfully, there are three ways:

The simplest way is:

```coffee
mkdir! "testsh" # will panic if mkdir failed
```

The second way is:

```coffee
mkdir "testsh"
lastErr!
```

Yes, `github.com/xushiwei/gsh` provides `lastErr` to check last error.

The third way is:

```coffee
mkdir "testsh"
if lastErr != nil {
panic lastErr
}
```

This is the most familiar way to Go developers.

### Capture output of commands

And, `github.com/xushiwei/gsh` provides a way to capture output of commands:

```coffee
capout => {
...
}
```

Similar to `lastErr`, the captured output result is saved to `output`.

For an example:

```coffee
capout => { ls "-l" }
println output
```

Here is a possible output:

```s
total 72
-rw-r--r-- 1 xushiwei staff 11357 Jun 19 00:20 LICENSE
-rw-r--r-- 1 xushiwei staff 127 Jun 19 10:00 README.md
-rw-r--r-- 1 xushiwei staff 365 Jun 19 00:25 example.gsh
-rw-r--r-- 1 xushiwei staff 126 Jun 19 09:33 go.mod
-rw-r--r-- 1 xushiwei staff 165 Jun 19 09:33 go.sum
-rw-r--r-- 1 xushiwei staff 110 Jun 19 09:33 gop.mod
-rw-r--r-- 1 xushiwei staff 1938 Jun 19 10:00 gop_autogen.go
```

We can use [Go+ powerful built-in data processing capabilities](doc/docs.md#data-processing) to process captured `output`:

```coffee
type file struct {
name string
fsize int
}

files := [file{flds[8], flds[4].int!} for e <- output.split("\n") if flds := e.fields; flds.len > 2]
```

In this example, we split `output` by `"\n"`, and for each entry `e`, split it by spaces (`e.fields`) and save into `flds`. Condition `flds.len > 2` is to remove special line of output:

```s
total 72
```

At last, pick file name and size of all selected entries and save into `files`.


### Implementation of gsh

To most developers, they just use `ClassFile`. They don't need to implement a `ClassFile` project.

We provide a `ClassFile` template project: [github.com/goplus/classfile-project-template](https://github.com/goplus/classfile-project-template).

TODO