Skip to content

Commit

Permalink
Merge pull request #799 from nevalang/tutorial-defer
Browse files Browse the repository at this point in the history
Props drilling, anonymous Interfaces, working filter, meta everywhere, etc
  • Loading branch information
emil14 authored Dec 15, 2024
2 parents 17893ce + ec41d5a commit 454720e
Show file tree
Hide file tree
Showing 208 changed files with 2,722 additions and 2,294 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ vendor
tmp
tmp.md
todo.md
docker-compose.yml
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/neva",
"cwd": "${workspaceFolder}/e2e",
"args": ["run", "--trace", "tutorial/src"]
"cwd": "${workspaceFolder}/e2e/filter_list",
"args": ["run", "--trace", "main"]
},
{
"name": "DEBUG CODEGEN",
Expand Down
7 changes: 6 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,10 @@
"scrollbar.shadow": "#00000000"
},
"svg.preview.background": "dark-transparent",
"vsicons.presets.angular": true
"vsicons.presets.angular": true,
"editor.tokenColorCustomizations": {
"[One Dark Pro Flat]": {
"comments": "#7f848e82"
}
}
}
27 changes: 27 additions & 0 deletions benchmarks/simplest_message_passing/bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package test

import (
"os"
"os/exec"
"testing"

"github.com/stretchr/testify/require"
)

func BenchmarkMessagePassing(b *testing.B) {
err := os.Chdir("..")
require.NoError(b, err)

wd, err := os.Getwd()
require.NoError(b, err)
defer os.Chdir(wd)

b.ResetTimer()

for i := 0; i < b.N; i++ {
cmd := exec.Command("neva", "run", "message_passing")
_, err := cmd.CombinedOutput()
require.NoError(b, err)
require.Equal(b, 0, cmd.ProcessState.ExitCode())
}
}
5 changes: 5 additions & 0 deletions benchmarks/simplest_message_passing/main.neva
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def Main(start any) (stop any) {
wait Wait
---
:start -> 1..1000 -> wait -> :stop
}
36 changes: 32 additions & 4 deletions cmd/lsp/indexer/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package indexer

import (
"context"
"path/filepath"
"strings"

"github.com/nevalang/neva/internal/builder"
"github.com/nevalang/neva/internal/compiler"
Expand All @@ -15,12 +17,38 @@ type Indexer struct {
analyzer analyzer.Analyzer
}

func (i Indexer) FullIndex(ctx context.Context, path string) (src.Build, *compiler.Error) {
feResult, err := i.fe.Process(ctx, path)
func (i Indexer) FullScan(
ctx context.Context,
workspacePath string,
) (src.Build, bool, *compiler.Error) {
feResult, err := i.fe.Process(ctx, workspacePath)
if err != nil {
return src.Build{}, err
return src.Build{}, false, err
}
return i.analyzer.AnalyzeBuild(feResult.ParsedBuild)

// if nevalang module is found, but it's not part of the workspace
if isParentPath(workspacePath, feResult.Path) {
return src.Build{}, false, nil
}

aBuild, err := i.analyzer.AnalyzeBuild(feResult.ParsedBuild)
if err != nil {
return src.Build{}, false, err
}

return aBuild, true, nil
}

func isParentPath(parent, child string) bool {
parent = filepath.Clean(parent)
child = filepath.Clean(child)

rel, err := filepath.Rel(parent, child)
if err != nil {
return false
}

return !strings.HasPrefix(rel, "..")
}

func New(
Expand Down
1 change: 1 addition & 0 deletions cmd/lsp/server/general_messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

func (s *Server) Initialize(glspCtx *glsp.Context, params *protocol.InitializeParams) (any, error) {
s.workspacePath = *params.RootPath

return protocol.InitializeResult{
Capabilities: s.handler.CreateServerCapabilities(),
ServerInfo: &protocol.InitializeResultServerInfo{
Expand Down
21 changes: 15 additions & 6 deletions cmd/lsp/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,29 @@ type Server struct {
index *src.Build

problemsMutex *sync.Mutex
problemFiles map[string]struct{}
problemFiles map[string]struct{} // we only need to store file urls but not their problems

activeFile string
activeFileMutex *sync.Mutex
}

// indexAndNotifyProblems does full scan of the workspace
// and sends diagnostics if there are any problems
func (s *Server) indexAndNotifyProblems(notify glsp.NotifyFunc) error {
build, err := s.indexer.FullIndex(context.Background(), s.workspacePath)
build, found, proplems := s.indexer.FullScan(
context.Background(),
s.workspacePath,
)

if !found {
return nil
}

s.indexMutex.Lock()
s.index = &build
s.indexMutex.Unlock()

if err == nil {
if proplems == nil {
// clear problems
s.problemsMutex.Lock()
for uri := range s.problemFiles {
Expand All @@ -60,13 +69,13 @@ func (s *Server) indexAndNotifyProblems(notify glsp.NotifyFunc) error {

// remember problem and send diagnostic
s.problemsMutex.Lock()
uri := filepath.Join(s.workspacePath, err.Location.String())
uri := filepath.Join(s.workspacePath, proplems.Meta.Location.String())
s.problemFiles[uri] = struct{}{}
notify(
protocol.ServerTextDocumentPublishDiagnostics,
s.createDiagnostics(*err, uri),
s.createDiagnostics(*proplems, uri),
)
s.logger.Info("diagnostic sent:", "err", err)
s.logger.Info("diagnostic sent:", "err", proplems)
s.problemsMutex.Unlock()

return nil
Expand Down
4 changes: 2 additions & 2 deletions docs/book/directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ def Main(start any) (stop any) {
lock Lock<string>
---
:start -> lock:sig
greeting:msg -> lock:data
greeting:res -> lock:data
lock:data -> println:data
println:sig -> :stop
println:res -> :stop
}
```

Expand Down
14 changes: 7 additions & 7 deletions docs/book/program_structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,26 @@ Module is usually a git-repo but not necessary. Module that isn't published in g

### Manifest File

The manifest defines the module's minimum supported language version and dependencies. Here's an example manifest with a dependency on the Nevalang compiler version `0.28.2` and a third-party module:
The manifest defines the module's minimum supported language version and dependencies. Here's an example manifest with a dependency on the Nevalang compiler version `0.29.0` and a third-party module:

```yaml
neva: 0.28.2
neva: 0.29.0
deps:
github.com/nevalang/x:
path: github.com/nevalang/x
version: 0.0.14
version: 0.0.16
```
The `deps` field is a map where each dependency has an alias. When adding dependencies via CLI (e.g., `neva get github.com/nevalang/x`), the package manager automatically inserts a key-value pair. Third-party dependencies must have a valid git-clone path and a fixed semver version. The package manager uses git to download the repo and looks for the corresponding git-tag. The alias typically defaults to the module's path, but custom aliases allow multiple versions of the same module:

> WIP: CLI tool planned for CI/CD to verify module's backward compatibility

```yaml
neva: 0.28.2
neva: 0.29.0
deps:
github.com/nevalang/x@0-0-12:
path: github.com/nevalang/x
version: 0.0.14
version: 0.0.16
github.com/nevalang/x@0-0-11:
path: github.com/nevalang/x
version: 0.0.11
Expand All @@ -71,7 +71,7 @@ Module references uniquely identify modules in a build, used by the compiler to

```yaml
path: github.com/nevalang/x
version: 0.0.14
version: 0.0.16
```

### Entry Module
Expand Down Expand Up @@ -312,7 +312,7 @@ Third-party imports are imports of packages located in third-party modules - mod
deps:
github.com/nevalang/x:
path: github.com/nevalang/x
version: 0.0.14
version: 0.0.16
```

Then when you `import { github.com/nevalang/x }` compiler will know exactly path and version of the module you are referring to.
Expand Down
6 changes: 3 additions & 3 deletions docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ After installation is finished, you should be able to run the `neva` CLI from yo
neva version
```

It should emit something like `0.28.2`
It should emit something like `0.29.0`

### Hello, World!

Expand Down Expand Up @@ -254,7 +254,7 @@ This structure introduces two fundamental concepts in Nevalang: modules and pack
A module is a set of packages with a manifest file (`neva.yaml`). When we created our project with `neva new`, it generated a basic module with the following manifest file:

```yaml
neva: 0.28.2
neva: 0.29.0
```
This defines the Nevalang version for our project. As your project grows, you can include dependencies on third-party modules here.
Expand Down Expand Up @@ -413,7 +413,7 @@ When chaining nodes, we actually reference their ports implicitly. The chain cou
```neva
:start -> 'World' -> greet:data
greet:res -> println:data
println:sig -> :stop
println:res -> :stop
```

Both versions are equivalent, but the chained syntax is preferred for readability.
Expand Down
41 changes: 28 additions & 13 deletions e2e/99_bottles_verbose/main/main.neva
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,28 @@ import { fmt }

def Main(start any) (stop any) {
// we use explicit lock to implement fan-in to printNext2Lines
s Switch<int>, PrintNext2Lines, Lock<int>
s Switch<int>
print_next_2_lines PrintNext2Lines
lock Lock<int>
---
:start -> lock:sig
99 -> lock:data
[lock:data, s:else] -> printNext2Lines
printNext2Lines -> s:data
[lock:data, s:else] -> print_next_2_lines
print_next_2_lines -> s:data
-1 -> s:case[0] -> :stop
}

def PrintNext2Lines(n int) (n int) {
Dec<int>, PrintFirstLine, PrintSecondLine
dec Dec<int>
print_first_line PrintFirstLine
print_second_line PrintSecondLine
---
// printFirstLine and printSecondLine won't work in parallel
// print_first_line and print_second_line won't work in parallel
// because they are in the loop at the level of Main
:n -> printFirstLine:n
printFirstLine:n -> dec:data
dec:res -> printSecondLine:n
printSecondLine:n -> :n
:n -> print_first_line:n
print_first_line:n -> dec:data
dec:res -> print_second_line:n
print_second_line:n -> :n
}

// === First Line ===
Expand All @@ -31,7 +35,12 @@ const firstLine2 string = '1 bottle of beer on the wall, 1 bottle of beer.'
const firstLine3 string = 'No more bottles of beer on the wall, no more bottles of beer.'

def PrintFirstLine(n int) (n int) {
s Switch<int>, p1 fmt.Println, p2 fmt.Println, fmt.Printf, Lock<int>, Panic
s Switch<int>
p1 fmt.Println
p2 fmt.Println
printf fmt.Printf
lock Lock<int>
panic Panic
---
:n -> [s:data, lock:data]

Expand All @@ -45,7 +54,7 @@ def PrintFirstLine(n int) (n int) {
$firstLine1 -> printf:tpl
]

[p1:sig, p2:sig, printf:sig] -> lock:sig
[p1:res, p2:res, printf:sig] -> lock:sig
printf:err -> panic
lock:data -> :n
}
Expand All @@ -58,7 +67,13 @@ const secondLine3 string = 'Take one down and pass it around, no more bottles of
const secondLine4 string = 'Go to the store and buy some more, 99 bottles of beer on the wall.'

def PrintSecondLine(n int) (n int) {
s Switch<int>, p1 fmt.Println, p2 fmt.Println, p3 fmt.Println, fmt.Printf, Lock<int>, Panic
s Switch<int>
p1 fmt.Println
p2 fmt.Println
p3 fmt.Println
printf fmt.Printf
lock Lock<int>
panic Panic
---
:n -> [s:data, lock:data]

Expand All @@ -75,7 +90,7 @@ def PrintSecondLine(n int) (n int) {
$secondLine1 -> printf:tpl
]

[p1:sig, p2:sig, p3:sig, printf:sig] -> lock:sig
[p1:res, p2:res, p3:res, printf:sig] -> lock:sig
printf:err -> panic
lock:data -> :n
}
2 changes: 1 addition & 1 deletion e2e/99_bottles_verbose/neva.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
neva: 0.28.2
neva: 0.29.0
2 changes: 1 addition & 1 deletion e2e/add_nums_from_stdin_naive/main/main.neva
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ def Main(start any) (stop any) {
scanner2:res -> parser2:data
parser2:res -> add:right
add:res -> println:data
println:sig -> :stop
println:res -> :stop
[parser1:err, parser2:err] -> panic
}
2 changes: 1 addition & 1 deletion e2e/add_nums_from_stdin_naive/neva.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
neva: 0.28.2
neva: 0.29.0
Loading

0 comments on commit 454720e

Please sign in to comment.