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
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
```lua
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.
```
ENTRY START
[START]{
"Hello It is now time to do some tests!"
a=15
"a = $a$"
b=a@25
test2="Yo $a$ $b$" -- create a string with a and b vars
"$test2$"
"b = $b$"
c=5
"c = $c$"
cf=10+(5!)+10
test=(5~5)+5
"c! = $cf$ test = $test$"
"All done"
JUMP(NOVAR)
}
[@:construct]{ -- get % out of 100
ret=l/(r/100)
return(ret)
}
[~:construct]{ -- negate variable
if r~=NONE then GOTO(sub)|GOTO(neg)
::sub::
ret=l-r
return(ret)
GOTO(end)
::neg::
ret=0-r
return(ret)
::end::
}
-- You dont have too many symbols left to use though. For now a symbol is only 1 char long so you are limited
[fact:function(n)]{
count=1
stop=n
::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"
::name::
name = getInput("Enter your name: ")
if name=="" then GOTO("name")|SKIP(0)
::good::
print("Player Name: $name$")
choice = getInput("Is this name correct? (y/n): ")
if choice=="y" then SKIP(0)|GOTO("name")
print("Let's play $name$!")
list=["r","p","s"]
list2=["rock","paper","scissors"]
list3=[]
list3["r"]="rock"
list3["p"]="paper"
list3["s"]="scissors"
::gameloop::
cpus_mov=random(1,3)
cpus_move=$list[cpus_mov]$
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")
a=$list2[cpus_mov]$
b=$list3[player_move]$
if player_move==cpus_move then print("We both played $b$, no one won...")|SKIP(0)
if cpus_move=="r" and player_move=="s" then print("I won $name$, you lose! You know $a$ beats $b$")|SKIP(0)
if cpus_move=="p" and player_move=="r" then print("I won $name$, you lose! You know $a$ beats $b$")|SKIP(0)
if cpus_move=="s" and player_move=="p" then print("I won $name$, you lose! You know $a$ beats $b$")|SKIP(0)
b=$list2[cpus_mov]$
a=$list3[player_move]$
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)
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)
::choice::
cho=getInput("That was a fun game! Do you want to play again? (y/n): ")
if cho=="y" then GOTO("gameloop")|SKIP(0)
if cho=="n" then print("Thanks for playing!")|SKIP(0)
}
```
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
```