Skip to content

Commit

Permalink
feat: allow using types from other packages
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnCoene committed Sep 15, 2024
2 parents 81564e9 + 7e1560e commit fdb75c6
Show file tree
Hide file tree
Showing 12 changed files with 451 additions and 165 deletions.
10 changes: 5 additions & 5 deletions diagnostics/diagnostics.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,26 +70,26 @@ func (d Diagnostics) String() string {
var out bytes.Buffer

for _, v := range d {
v.Print()
out.WriteString(v.String())
}

return out.String()
}

func (v Diagnostic) Print() {
func (v Diagnostic) String() string {
var out bytes.Buffer
out.WriteString("[" + prefix(v.Severity) + "]\t")
out.WriteString(v.Token.File)
out.WriteString(":")
out.WriteString(fmt.Sprintf("%v", v.Token.Line))
out.WriteString(":")
out.WriteString(fmt.Sprintf("%v", v.Token.Char))
out.WriteString(" " + v.Message)
fmt.Println(out.String())
out.WriteString(" " + v.Message + "\n")
return out.String()
}

func (d Diagnostics) Print() {
fmt.Println(d.String())
fmt.Printf("%v", d.String())
}

func prefix(s Severity) string {
Expand Down
66 changes: 48 additions & 18 deletions environment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ type Environment struct {
outer *Environment
}

var library string

func SetLibrary(path string) {
library = path
}

func Enclose(outer *Environment, t ast.Types) *Environment {
env := New()
env.returnType = t
Expand Down Expand Up @@ -67,7 +73,7 @@ var baseObjects = []string{
"impliedList",
}

func New() *Environment {
func NewGlobalEnvironment() *Environment {
v := make(map[string]Variable)
t := make(map[string]Type)
f := make(map[string]Function)
Expand All @@ -90,7 +96,7 @@ func New() *Environment {
}

for _, t := range baseTypes {
env.SetType(t, Type{Used: true, Type: []*ast.Type{{Name: t, List: false}}})
env.SetType(Type{Used: true, Name: t, Type: []*ast.Type{{Name: t, List: false}}})
}

fns, err := r.ListBaseFunctions()
Expand All @@ -109,6 +115,29 @@ func New() *Environment {
return env
}

func New() *Environment {
v := make(map[string]Variable)
t := make(map[string]Type)
f := make(map[string]Function)
c := make(map[string]Class)
m := make(map[string]Matrix)
s := make(map[string]Signature)
fct := make(map[string]Factor)
meth := make(map[string]Methods)

return &Environment{
functions: f,
variables: v,
types: t,
class: c,
matrix: m,
signature: s,
factor: fct,
method: meth,
outer: nil,
}
}

func (e *Environment) SetSignatureUsed(name string) (Signature, bool) {
obj, ok := e.signature[name]

Expand All @@ -122,11 +151,11 @@ func (e *Environment) SetSignatureUsed(name string) (Signature, bool) {
return obj, ok
}

func (e *Environment) SetTypeUsed(name string) (Type, bool) {
obj, ok := e.types[name]
func (e *Environment) SetTypeUsed(pkg, name string) (Type, bool) {
obj, ok := e.types[makeTypeKey(pkg, name)]

if !ok && e.outer != nil {
return e.outer.SetTypeUsed(name)
return e.outer.SetTypeUsed(pkg, name)
}

obj.Used = true
Expand Down Expand Up @@ -182,28 +211,29 @@ func (e *Environment) SetVariableNotMissing(name string) {
e.SetVariable(name, v)
}

func (e *Environment) GetType(name string) (Type, bool) {
obj, ok := e.types[name]
if !ok && e.outer != nil {
obj, ok = e.outer.GetType(name)
func makeTypeKey(pkg, name string) string {
if pkg == "" {
return name
}

if ok {
e.SetTypeUsed(name)
}
return obj, ok
return pkg + "::" + name
}

func makeTypeKey(val Type) string {
if val.Package == "" {
return val.Name
func (e *Environment) GetType(pkg, name string) (Type, bool) {
obj, ok := e.types[makeTypeKey(pkg, name)]
if !ok && e.outer != nil {
obj, ok = e.outer.GetType(pkg, name)
}

if ok {
e.SetTypeUsed(pkg, name)
}

return val.Package + "::" + val.Name
return obj, ok
}

func (e *Environment) SetType(val Type) Type {
e.types[makeTypeKey(val)] = val
e.types[makeTypeKey(val.Package, val.Name)] = val
return val
}

Expand Down
80 changes: 79 additions & 1 deletion environment/types.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package environment

import (
"errors"
"os"
"path"
"strings"

"github.com/devOpifex/vapour/ast"
"github.com/devOpifex/vapour/lexer"
"github.com/devOpifex/vapour/parser"
)

type Code struct {
Expand Down Expand Up @@ -51,7 +56,7 @@ func (e *Environment) GenerateTypes() *Code {

for i, a := range typeObject.Attributes {
sep := ""
if i > len(typeObject.Attributes)-1 {
if i < len(typeObject.Attributes)-1 {
sep = ","
}
code.add("\t" + a.Name + ": " + collaseTypes(a.Type) + sep)
Expand Down Expand Up @@ -96,3 +101,76 @@ func IsNativeObject(name string) bool {
}
return false
}

var packagesLoaded []string

func isLoaded(library string) bool {
for _, p := range packagesLoaded {
if p == library {
return true
}
}

return false
}

func (env *Environment) LoadPackageTypes(pkg string) error {
if library == "" {
return nil
}

if isLoaded(pkg) {
return nil
}

packagesLoaded = append(packagesLoaded, library)

typeFile := path.Join(library, pkg, "types.vp")

if _, err := os.Stat(typeFile); errors.Is(err, os.ErrNotExist) {
return err
}

content, err := os.ReadFile(typeFile)

if err != nil {
return err
}

// lex
l := lexer.NewCode(typeFile, string(content))
l.Run()

if l.HasError() {
return errors.New("failed to lex types file")
}

// parse
p := parser.New(l)
prog := p.Run()

if p.HasError() {
return errors.New("failed to lex types file")
}

// range over the Statements
// these should all be type declarations
for _, p := range prog.Statements {
switch node := p.(type) {
case *ast.TypeStatement:
env.SetType(
Type{
Token: node.Token,
Type: node.Type,
Attributes: node.Attributes,
Object: node.Object,
Name: node.Name,
Package: pkg,
Used: true,
},
)
}
}

return nil
}
58 changes: 58 additions & 0 deletions r/args.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package r

import (
"encoding/json"
"fmt"

"github.com/devOpifex/vapour/ast"
)

type arg struct {
Name string `json:"name"`
Value string `json:"value"`
}

type args []arg

func GetFunctionArguments(pkg, operator, function string) *ast.FunctionLiteral {
obj := &ast.FunctionLiteral{}
function = pkg + operator + function

output, err := Callr(
fmt.Sprintf(`args <- as.list(args(%v))
if(length(args) == 0){
cat("[]")
return()
}
N <- length(args) - 1L
args <- args[1:N]
json_string <- c()
for(i in seq_along(args)) {
arg_string <- paste0(
'{"name": "', names(args)[i], '", "value": "', deparse(args[i]), '"}'
)
json_string <- c(json_string, arg_string)
}
json_string <- paste0(json_string, collapse = ",")
cat(paste0("[", json_string, "]"))`,
function,
),
)

if err != nil {
return obj
}

var args args

err = json.Unmarshal(output, &args)

if err != nil {
return obj
}

return obj
}
7 changes: 0 additions & 7 deletions r/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ import (
"fmt"

"github.com/devOpifex/vapour/cache"
"github.com/devOpifex/vapour/config"
)

var library string

type Package struct {
Name string `json:"name"`
Functions []string `json:"functions"`
Expand All @@ -20,10 +17,6 @@ const (
FUNCTION = "FUNCTION"
)

func Setup(args config.Config) {
library = string(args.Library)
}

func ListBaseFunctions() ([]Package, error) {
c, ok := cache.Get(BASEPACKAGES)

Expand Down
32 changes: 0 additions & 32 deletions r/types.go

This file was deleted.

3 changes: 3 additions & 0 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/devOpifex/vapour/cli"
"github.com/devOpifex/vapour/config"
"github.com/devOpifex/vapour/devtools"
"github.com/devOpifex/vapour/environment"
"github.com/devOpifex/vapour/lsp"
)

Expand All @@ -33,6 +34,8 @@ func run(code string) {
func (v *vapour) Run(args cli.CLI) {
v.config = config.ReadConfig()

environment.SetLibrary(string(v.config.Library))

if *args.Indir != "" {
ok := v.transpile(args)
devtools.Run(ok, args)
Expand Down
Loading

0 comments on commit fdb75c6

Please sign in to comment.