This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Emma's profile picture

Sammich Compiler

Started by Emma, 27 November 2014 - 04:54 PM
Emma #1
Posted 27 November 2014 - 05:54 PM
Now, before all the haters hate on me, this is very very very simplified and not very far. I just got bored and decided to make my own little tiny itty bitty lanuage. I dubbed it 'Sammich'.

The syntax is very simple, here is an example file:

print
  "Hello there!"
print
  "What's your name?"
read
  name
store
  startStr
  "Hi "
concat
  startStr
  name
print
  startStr
You should be able to make your own tokens fairly simply.
It translates it into lua, so yeah.
Could be useful for those just beginning with lua.

Notes:
SpoilerNesting Functions Currently Does Not Work

Here is the compiler: pastebin get 8rLJHTcR sammc
Edited on 27 November 2014 - 05:38 PM
ElvishJerricco #2
Posted 27 November 2014 - 08:46 PM
This looks a bit like an assembly language, where instead of having complex expressions and control, you just have instructions. Very interesting.
0099 #3
Posted 29 November 2014 - 01:22 PM
Let me change some parts of the translation loop
Spoiler

local endLine = ""
local kk = 1
repeat
  endLine = endLine..(v[2][kk] or "")
  endLine = endLine..(fArgs[v[2][kk+1]] or "")
  kk = kk+2
until kk>#v[2]
endLine = endLine..v[3]
return endLine
1. Instead of having such strict token structure, with string-number pairs, you can use the type() function, which returns the name of the type of the given variable, as a string. So, IF the element is a string, just write it. IF it is a number, write an argument with that number.

local endLine = ""
local kk = 1
repeat
  if type(v[2][kk]) == "string" then
    endLine = endLine..(v[2][kk] or "")
  else
    endLine = endLine..(fArgs[v[2][kk]] or "")
  end
  kk = kk+1
until kk>#v[2]
endLine = endLine..v[3]
return endLine
2. As you can see now, it is clearly just a FOR loop. So, repeat..until is unneccesary.

local endLine = ""
for kk=1,#v[2] do
  if type(v[2][kk]) == "string" then
    endLine = endLine..(v[2][kk] or "")
  else
    endLine = endLine..(fArgs[v[2][kk]] or "")
  end
end
endLine = endLine..v[3]
return endLine
By the way, you could do it with a FOR loop before, even with the step of 2, because the third parameter of a FOR loop is the step (like "for kk=1,#v[2],2 do")
3. Now, as you process exactly #v[2] elements, the or "" part is absolutely unneccesary.

local endLine = ""
for kk=1,#v[2] do
  if type(v[2][kk]) == "string" then
    endLine = endLine..v[2][kk]
  else
    endLine = endLine..fArgs[v[2][kk]]
  end
end
endLine = endLine..v[3]
return endLine
4. Finally, as you now can have v[2] elements in any order you want, you don't need v[3]. You can just include that string in v[2].

local endLine = ""
for kk=1,#v[2] do
  if type(v[2][kk]) == "string" then
    endLine = endLine..v[2][kk]
  else
    endLine = endLine..fArgs[v[2][kk]]
  end
end
return endLine
Now the definitions will look like this:

local funcs = {
  ["print"] = {
	1,
	{ "print(",1,")" },
  },
  ["store"] = {
	2,
	{ 1," = ",2 },
  },
  ["concat"] = {
	2,
	{ 1," = ",1,"..",2 },
  },
  ["read"] = {
	1,
	{ 1," = read()" },
  }
}

Also, in this kind of languages, nesting functions just aren't the case. You should run them one by one, storing their results in temporary variables.
Edited on 29 November 2014 - 12:31 PM