Readme updated

reflects the new features in the library
This commit is contained in:
Ryan Ward 2019-01-07 10:34:19 -05:00 committed by GitHub
parent abfd69ffe1
commit 350a2e7e30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

452
README.md
View File

@ -3,424 +3,44 @@
A module for making advance config files. This library depends on my multi library and my bin library A module for making advance config files. This library depends on my multi library and my bin library
Here is an example, this would be its own file called parsetest.txt Here is an example, this would be its own file called parsetest.txt
```lua
ENTRY START
ENABLE forseelabels
DISABLE leaking
ENABLE customcommands -- WIP
USING EBIM -- Allows for multilined commands
[START]{
--Defualt enviroment is the GLOBAL one, you can create and swap between them whenever you want. You can have as many as you want as well
a=100
b=7
c=21
"$a$ $b$ $c$"
env=createENV()
setENV(env)
a=15
b=150
"$a$ $b$ $c$"
env=getENV("GLOBAL")
setENV(env)
"$a$ $b$ $c$"
test=a<-env -- get var a from an env and set it to test
"Test $test$"
test=51
a=test->env -- set var a in env to test
"$a$ $b$ $c$"
setENV(env) -- lets go back to the modified enviroment
"$a$ $b$ $c$"
test2=stringLEN("$a$ $b$ $c$")
"Test2 $test2$"
string test5: -- no need for quotes, everything in the block is considered a string... Also no escaping is needed; however, endstring is not useable as a part of the string...
Yo I am able to make a multilined string if i want
Now I am at the next line lol!
endstring
list test6: -- create a multilined list
"elem1"
2
3
true
false
"elem6"
env
endlist
dict test7:
name: "Bob"
age: 99
job: "Admin"
list: test6
enddict
"Test5 $test5$"
list=[1,2,3,4]
test4=list[2]
env["a"]=10
test3=env["a"]
"Test3 $test3$"
"List $test6[1]$"
"List $test6[2]$"
"List $test6[3]$"
"List $test6[4]$"
"List $test6[5]$"
"List $test6[6]$"
"List $test6[7]$"
"Dict $test7[name]$"
"Dict $test7[age]$"
"Dict $test7[job]$"
test9="name"
test8=test7[test9]
"Test8 $test8$"
data=test7[list]
data2=data[1]
"Test9 $data2$"
data=tester2(1,2,3)
"Now what are these $a$ $b$ $c$"
"$data[name]$"
"$data[me]$"
::choices::
"Pick?"<
"test1" JUMP(C1)
"test2" JUMP(C2)
"test3" JUMP(C3)
>
-- if name=="bob" or name=="ryan":
-- "ADMINS"
-- elseif name=="Joe"
-- "NOT ADMIN"
-- else
-- "Something else"
-- endif
}
[C1]{
"Hello1"
GOTO(choices)
}
[C2]{
"Hello2"
GOTO(choices)
}
[C3]{
"Hello3"
GOTO(choices)
}
[@:construct]{ -- l is left arg r is the right arg
ret=l*(r/100)
return(ret)
}
[tester:function]{
"lets go"
nest="hey"
}
[tester2:function(a,b,c)]{ -- functions return enviroments which can be indexed
"Interesting: $a$ $b$ $c$"
name="Ryan"
age=15
yo=tester()
me=yo["nest"]
}
```
parsetest2.txt There have been massive changes to syntax and how the library works. I will include a notepad++ file for syntax highlighting. I will eventually update the C# version of this script.
```lua ```
ENTRY START ENTRY START
[START]{ [START]{
"Hello It is now time to do some tests!" ::name::
a=15 name = getInput("Enter your name: ")
"a = $a$" if name=="" then GOTO("name")|SKIP(0)
b=a@25 ::good::
test2="Yo $a$ $b$" -- create a string with a and b vars print("Player Name: $name$")
"$test2$" choice = getInput("Is this name correct? (y/n): ")
"b = $b$" if choice=="y" then SKIP(0)|GOTO("name")
c=5 print("Let's play $name$!")
"c = $c$" list=["r","p","s"]
cf=10+(5!)+10 list2=["rock","paper","scissors"]
test=(5~5)+5 list3=[]
"c! = $cf$ test = $test$" list3["r"]="rock"
"All done" list3["p"]="paper"
JUMP(NOVAR) list3["s"]="scissors"
} ::gameloop::
[@:construct]{ -- get % out of 100 cpus_mov=random(1,3)
ret=l/(r/100) cpus_move=$list[cpus_mov]$
return(ret) player_move = getInput("Enter 'r' 'p' or 's': ")
} if player_move=="r" or player_move=="p" or player_move=="s" then SKIP(0)|GOTO("gameloop")
[~:construct]{ -- negate variable a=$list2[cpus_mov]$
if r~=NONE then GOTO(sub)|GOTO(neg) b=$list3[player_move]$
::sub:: if player_move==cpus_move then print("We both played $b$, no one won...")|SKIP(0)
ret=l-r if cpus_move=="r" and player_move=="s" then print("I won $name$, you lose! You know $a$ beats $b$")|SKIP(0)
return(ret) if cpus_move=="p" and player_move=="r" then print("I won $name$, you lose! You know $a$ beats $b$")|SKIP(0)
GOTO(end) if cpus_move=="s" and player_move=="p" then print("I won $name$, you lose! You know $a$ beats $b$")|SKIP(0)
::neg:: b=$list2[cpus_mov]$
ret=0-r a=$list3[player_move]$
return(ret) if player_move=="r" and cpus_move=="s" then print("$name$ you won wow! I guess my $b$ was no match for your $a$")|SKIP(0)
::end:: if player_move=="p" and cpus_move=="r" then print("$name$ you won wow! I guess my $b$ was no match for your $a$")|SKIP(0)
} if player_move=="s" and cpus_move=="p" then print("$name$ you won wow! I guess my $b$ was no match for your $a$")|SKIP(0)
-- You dont have too many symbols left to use though. For now a symbol is only 1 char long so you are limited ::choice::
[fact:function(n)]{ cho=getInput("That was a fun game! Do you want to play again? (y/n): ")
count=1 if cho=="y" then GOTO("gameloop")|SKIP(0)
stop=n if cho=="n" then print("Thanks for playing!")|SKIP(0)
::loop:: -- for loop kinda, can become a stateloop as well
n=n*count
count=count+1
if count==stop then GOTO(end)|GOTO(loop)
::end::
ret=n
}
[neg:function(n)]{
ret=n*(0-1)
}
--Bind the fact function to the symbol '!'
[!:construct]{
env=fact(l)
ret=ret<-env
return(ret)
}
[NOVAR]{
::go::
"I AM HERE!!!"
NOVAR="TEST"
JUMP(START)
}
[TEST]{
"We are now here"
} }
``` ```
Here is the luacode using the library. NOTE: I was doing tests so the test code has blocks of code that should be within the module itself!
main.lua
```lua
require("bin")
require("multi.all")
require("parseManager")
function parseManager:RunCode(code,entry,sel,env) -- returns an env or selectVarName
local file = bin.new("ENTRY "..(entry or "START").."\n"..code)
local run=parseManager:load(file)
run._methods = self._methods
run.defualtENV=self.defualtENV
run.defualtENV=self.defualtENV
for i,v in pairs(env or {}) do
run.defualtENV[i]=v
end
local t=run:start()
while true do
if t.Type=="text" then
print(t.text)
t=run:next()
elseif t.Type=="condition" then
t=run:next()
elseif t.Type=="assignment" then
t=run:next()
elseif t.Type=="label" then
t=run:next()
elseif t.Type=="method" then
t=run:next()
elseif t.Type=="choice" then
t=run:next(nil,math.random(1,#t.choices),nil,t)
elseif t.Type=="end" then
if t.text=="leaking" then -- go directly to the block right under the current block if it exists
t=run:next()
else
return (run.defualtENV[sel] or run.defualtENV)
end
elseif t.Type=="error" then
error(t.text)
else
t=run:next()
end
end
end
parseManager.symbols={} -- {sym,code}
function parseManager:registerSymbol(sym,code)
self.symbols[#self.symbols+1]={sym,code}
end
function parseManager:populateSymbolList(o)
local str=""
for i=1,#self.symbols do
str=self.symbols[i][1]..str
end
return str
end
function parseManager:isRegisteredSymbol(o,r,v)
for i=1,#self.symbols do
if self.symbols[i][1]==o then
return parseManager:RunCode(self.symbols[i][2],"CODE","ret-urn",{["l"]=r,["r"]=v,["mainenv"]=self.defualtENV})
end
end
return false --self:pushError("Invalid Symbol "..o.."!")
end
function parseManager:evaluate(cmd,v)
v=v or 0
local loop
local count=0
local function helper(o,v,r)
if type(v)=="string" then
if v:find("%D") then
v=self:varExists(v)
end
end
if type(r)=="string" then
if r:find("%D") then
r=self:varExists(r)
end
end
local r=tonumber(r) or 0
local gg=self:isRegisteredSymbol(o,r,v)
if gg then
return gg
elseif o=="+" then
return r+v
elseif o=="-" then
return r-v
elseif o=="/" then
return r/v
elseif o=="*" then
return r*v
elseif o=="^" then
return r^v
end
end
for i,v in pairs(math) do
cmd=cmd:gsub(i.."(%b())",function(a)
a=a:sub(2,-2)
if a:sub(1,1)=="-" then
a="0"..a
end
return v(self:evaluate(a))
end)
end
cmd=cmd:gsub("%b()",function(a)
return self:evaluate(a:sub(2,-2))
end)
for l,o,r in cmd:gmatch("(.*)([%+%^%-%*/"..self:populateSymbolList().."])(.*)") do
loop=true
count=count+1
if l:find("[%+%^%-%*/]") then
v=self:evaluate(l,v)
v=helper(o,r,v)
else
if count==1 then
v=helper(o,r,l)
end
end
end
if not loop then return self:varExists(cmd) end
return v
end
parseManager.constructType=function(self,name,t,data,filename)
if t~="construct" then return end
--print(name,t,"[CODE]{"..data.."}")
self:registerSymbol(name,"[CODE]{"..data.."}")
end
parseManager.OnExtendedBlock(parseManager.constructType)
test=parseManager:load("parsetest2.txt") -- load the file
t=test:start()
while true do
if t.Type=="text" then
print(t.text)
t=test:next()
elseif t.Type=="condition" then
t=test:next()
elseif t.Type=="assignment" then
t=test:next()
elseif t.Type=="label" then
t=test:next()
elseif t.Type=="method" then
t=test:next()
elseif t.Type=="choice" then
print(t.text)
for i=1,#t.choices do
print(i..". "..t.choices[i])
end
io.write("Choose#: ")
cm=tonumber(io.read())
t=test:next(nil,cm,nil,t)
elseif t.Type=="end" then
if t.text=="leaking" then -- go directly to the block right under the current block if it exists
t=test:next()
else
os.exit()
end
elseif t.Type=="error" then
error(t.text)
else
t=test:next()
end
end
```
# Output if using parsetest.txt
```
100 7 21
15 150 21
100 7 21
Test 15
100 7 21
51 150 21
Test2 9
Test5 Yo I am able to make a multilined string if i want
Now I am at the next line lol!
Test3 10
List elem1
List 2
List 3
List true
List false
List elem6
List table: 00B53B98
Dict Bob
Dict 99
Dict Admin
Test8 Bob
Test9 data[1]
Interesting: 1 2 3
lets go
Now what are these 51 150 21
Ryan
hey
Pick?
1. test1
2. test2
3. test3
Choose#: 2
Hello2
Pick?
1. test1
2. test2
3. test3
Choose#: 3
Hello3
Pick?
1. test1
2. test2
3. test3
Choose#: 1
Hello1
Pick?
1. test1
2. test2
3. test3
Choose#: Pick?
1. test1
2. test2
3. test3
Choose#:
... Would continue forever
```
# Output if running parsetest2.txt
```
Hello It is now time to do some tests!
a = 15
Yo 15 60
b = 60
c = 5
c! = 140 test = 5
All done
I AM HERE!!!
Hello It is now time to do some tests!
a = 15
Yo 15 60
b = 60
c = 5
c! = 140 test = 5
All done
We are now here
```