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

Refactor/import feature #11

Merged
merged 3 commits into from
May 17, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 1 addition & 22 deletions Evaluator/BuiltIn.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,29 +158,8 @@ func ImportLibrary(env *Environment) (iObject, error) {
}
pathLibraryOb.Value = strings.Replace(pathLibraryOb.Value, "/", string(os.PathSeparator), -1)
path := filepath.Join(localPath, pathLibraryOb.Value)
println(path)
_, e = Run(path, env)
if e != nil {
return nil, e
}
if len(env.variables) > 1 {
for name, f := range env.variables {
if name == "path" {
continue
}
if _, ok := f.(Parser.FuncDeclarationStatement); !ok {
return nil, errors.New("not possible define variables in library")
}
}
}
partsPath := strings.Split(pathLibraryOb.Value, string(os.PathSeparator))
pathLibraryOb.Value = partsPath[len(partsPath)-1]
var newName string
for name, funct := range env.functions {
newName = pathLibraryOb.Value[:len(pathLibraryOb.Value)-4] + "_" + name
env.externals.addFunction(newName, funct)
}
return nil, nil
return libraryObject{name: pathLibraryOb.Value, env: env}, e
}
func LoadBuiltInFunction(env *Environment) {
env.addBuiltInFunc("len", builtInFuncObject{Name: "len", NameParams: []string{"a"}, BuiltInfunc: lenBuiltin})
Expand Down
69 changes: 41 additions & 28 deletions Evaluator/CallFunc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package Evaluator
import (
"FLanguage/Parser"
"errors"
"strings"
)

func evalCallFunc(expression Parser.ExpresionCallFunc, env *Environment) (iObject, error) {
envFunc := &Environment{
funcEnv := &Environment{
variables: make(map[string]iObject),
functions: make(map[string]Parser.FuncDeclarationStatement),
externals: env,
Expand All @@ -15,49 +16,45 @@ func evalCallFunc(expression Parser.ExpresionCallFunc, env *Environment) (iObjec
}
var fun Parser.FuncDeclarationStatement
var e error
switch ident := expression.Identifier.(type) {
switch ident := expression.Called.(type) {
case Parser.ExpresionLeaf:
funcBuiltInObject, ok := env.getBuiltInFunc(ident.Value)
if ok == nil {
return callBuiltInFunc(expression, funcBuiltInObject, envFunc)
return callBuiltInFunc(expression, funcBuiltInObject, funcEnv)
}
fun, e = env.getFunction(ident.Value)
if e != nil {
inlineVar, e := env.getVariable(ident.Value)
if t, e := getFunctionInLeaf(env, ident); e == nil {
fun = t.(Parser.FuncDeclarationStatement)
}

default:
hashGet, isHashGet := expression.Called.(Parser.ExpresionGetValueHash)
if isHashGet {
hash, e := evalExpresion(hashGet.Value, env)
if e != nil {
return nil, e
}
inlineFun, ok := inlineVar.(Parser.FuncDeclarationStatement)
if !ok {
return nil, errors.New("not a function")
if lib, ok := hash.(libraryObject); ok {
funcEnv.functions = lib.env.functions
fun, e = lib.env.getFunction(strings.Split(hashGet.Index.ToString(), `"`)[1])
}
fun = inlineFun
funcEnv.addVariable("this", hash)
}
default:
funct, e := evalExpresion(expression.Identifier, env)
funct, e := evalExpresion(expression.Called, env)
if e != nil {

return nil, e
}
hashGet, ok := expression.Identifier.(Parser.ExpresionGetValueHash)
if ok {
hash, e := evalExpresion(hashGet.Value, env)
if e != nil {
return nil, e
}
envFunc.addVariable("this", hash)
}
fun, ok = funct.(Parser.FuncDeclarationStatement)
if !ok {
return nil, errors.New("not a function")
tfun := fun
fun, isHashGet = funct.(Parser.FuncDeclarationStatement)
if !isHashGet {
fun = tfun
}
}
if len(fun.Params) != len(expression.Values) {
if len(fun.Params) != len(expression.Params) {
return nil, errors.New("not enough parms")
}
evalParms(expression.Values, fun.Params, envFunc)
evalParms(expression.Params, fun.Params, funcEnv)

valExp, e := Eval(fun.Body.(*Parser.StatementNode), envFunc)
valExp, e := Eval(fun.Body.(*Parser.StatementNode), funcEnv)
if e != nil {
return nil, e

Expand All @@ -69,8 +66,24 @@ func evalCallFunc(expression Parser.ExpresionCallFunc, env *Environment) (iObjec
return v.Value, nil
}

func getFunctionInLeaf(envSource *Environment, ident Parser.ExpresionLeaf) (iObject, error) {

fun, e := envSource.getFunction(ident.Value)
if e != nil {
inlineVar, e := envSource.getVariable(ident.Value)
if e != nil {
return nil, e
}
inlineFun, ok := inlineVar.(Parser.FuncDeclarationStatement)
if !ok {
return nil, errors.New("not a function")
}
return inlineFun, nil
}
return fun, e
}
func callBuiltInFunc(expression Parser.ExpresionCallFunc, funcBuiltInObject builtInFuncObject, env *Environment) (iObject, error) {
err := evalParms(expression.Values, funcBuiltInObject.NameParams, env)
err := evalParms(expression.Params, funcBuiltInObject.NameParams, env)
if err != nil {
return nil, err
}
Expand Down
4 changes: 4 additions & 0 deletions Evaluator/Expresion.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,11 @@ func evalExpresion(expresion Parser.IExpresion, env *Environment) (iObject, erro
if e != nil {
return nil, e
}
if b, ok := hash.(libraryObject); ok {
return b, nil
}
hash, ok := hash.(hashObject).Values[key]

if !ok {
return nil, errors.New("element not found")
}
Expand Down
10 changes: 5 additions & 5 deletions Evaluator/StandardLibrary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (

func TestBinarySearch(t *testing.T) {
ist := `
import("../Library/BinarySearch.txt");
let binary=import("../Library/BinarySearch.txt");
let list=[2,6,7,9,22,44,55,66,77,88,99];
let b=BinarySearch_Run(list,66);
let b=binary{"Run"}(list,66);
END
`
lexer, e := Lexer.New([]byte(ist))
Expand Down Expand Up @@ -46,10 +46,10 @@ func TestBinarySearch(t *testing.T) {

func TestTree(t *testing.T) {
ist := `
import("../Library/Tree.txt");
let tree=import("../Library/Tree.txt");
let list=[22,21,6,7,9,0,55,6,-20,88,99];
let node=Tree_MakeTree(list);
let orderedList=Tree_FromTreeToList(node,len(list));
let node=tree{"MakeTree"}(list);
let orderedList=tree{"FromTreeToList"}(node,len(list));
END
`
lexer, e := Lexer.New([]byte(ist))
Expand Down
9 changes: 9 additions & 0 deletions Evaluator/StructObject.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,12 @@ func (b builtInFuncObject) ToString() string {
}
return r + ")"
}

type libraryObject struct {
name string
env *Environment
}

func (l libraryObject) ToString() string {
return "Env" + l.name
}
Binary file added FLanguage.exe
Binary file not shown.
15 changes: 7 additions & 8 deletions Library/Tree.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ Ff AddNode(value,node){
ret [[],value,[]];
}
if(value>node[1]){
node[2]=Tree_AddNode(value,node[2]);
node[2]=AddNode(value,node[2]);
}else{
node[0]=Tree_AddNode(value,node[0]);
node[0]=AddNode(value,node[0]);
}
ret node;
}

Ff MakeTree(list){
let i=1;
let node=[[],list[0],[]];
let ordered=newArray(len(list),0);
let ordered=newArray(len(list),0);
let v=0;
while(i<len(list)){
Tree_AddNode(list[i],node);
AddNode(list[i],node);
ordered[i]=v;
i=i+1;
}
Expand All @@ -25,20 +25,19 @@ Ff MakeTree(list){
Ff interateTreeNodes(node,i,list){

if(len(node[0])!=0){
Tree_interateTreeNodes(node[0],i,list);
interateTreeNodes(node[0],i,list);
}
list[i[0]]=node[1];
i[0]=i[0]+1;

if(len(node[2])!=0){
Tree_interateTreeNodes(node[2],i,list);
interateTreeNodes(node[2],i,list);
}
}
Ff FromTreeToList(node,n){

let i=[0];
let list=newArray(n,0);
Tree_interateTreeNodes(node,i,list);
interateTreeNodes(node,i,list);
ret list;
}
END
4 changes: 2 additions & 2 deletions Parser/ExpresionCallFunc.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import (
)

func expresionCallFunc(l *Lexer.Lexer, back IExpresion, _ ...Token.TokenType) (IExpresion, error) {
callFunc := ExpresionCallFunc{Identifier: back}
callFunc := ExpresionCallFunc{Called: back}
l.IncrP()
parms, e := ParseExpresionsGroup(l, nil, Token.CLOSE_CIRCLE_BRACKET, Token.COMMA)
callFunc.Values = parms
callFunc.Params = parms
if e != nil {
return nil, e
}
Expand Down
12 changes: 6 additions & 6 deletions Parser/ExpresionObjects.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,22 @@ func (_ ExpresionLeaf) New(t Token.Token) ExpresionLeaf {
}

type ExpresionCallFunc struct {
Values []IExpresion
Identifier IExpresion
Params []IExpresion
Called IExpresion
}

func (e *ExpresionCallFunc) AddParm(value IExpresion) {
e.Values = append(e.Values, value)
e.Params = append(e.Params, value)
}
func (e ExpresionCallFunc) ToString() string {
r := e.Identifier.ToString() + "("
r := e.Called.ToString() + "("
i := 0
for {

if i == len(e.Values) {
if i == len(e.Params) {
break
}
r += e.Values[i].ToString() + ","
r += e.Params[i].ToString() + ","
i++
}
r += ")"
Expand Down
Loading