Skip to content

Instantly share code, notes, and snippets.

@sdimitro
Created January 27, 2015 20:48
Show Gist options
  • Save sdimitro/d5dc8bd844c4e7d85d45 to your computer and use it in GitHub Desktop.
Save sdimitro/d5dc8bd844c4e7d85d45 to your computer and use it in GitHub Desktop.
Rudimentary lisp to C translation
# Note: The algorithms in the parsing section
# were described by Peter Norvig.
# Warning: I assume that all input is correct
# and only integers and binop functions take place.
# Data Structures for the Transpiller
var_defs = []
# Translation Methods
# Source Generating Related Variables
include_macro = "#include <stdio.h>\n"
main_func_ent = "int main() {"
main_func_ret = "}"
intermediate_src = ""
c_src = ""
# Get Lisp Source
#lisp_src = gets
# Source to Source Translation
## Parsing Methods
def is_int?(token)
token =~ /\A\d+\z/ ? true : false
end
def tokens(input)
input.gsub!('(',' ( ').gsub!(')',' ) ').split
end
def atom(token)
is_int?(token) ? token.to_i : token
end
def read_from_tokens(tokens)
raise 'unexpected EOF while reading' if tokens.empty?
token = tokens.shift
if token == '('
expr = []
until tokens[0] == ')'
expr.push(read_from_tokens(tokens))
end
tokens.shift # take out ')'
return expr
elsif token == ')'
raise 'unexpected )'
else
return atom(token)
end
end
def parse(program)
read_from_tokens(tokens(program))
end
## Translating Methods
def translate_expr(expr)
token = expr.shift
statement = ""
if token == 'def'
statement << 'int '
statement << expr.shift
statement << ' = '
if expr[0].kind_of?(Array)
statement << translate_expr(expr[0])
else
statement << expr.shift.to_s
statement << ';'
end
elsif token =~ /[\+|\-|\*]/
statement << expr.shift.to_s
statement << ' ' << token
statement << ' ' << expr.shift.to_s
statement << ';'
else
raise 'Yo dawg! I\'m not that smart yet!'
end
statement
end
def translate(parsed_output)
istatements = []
parsed_output.each do |expr|
istatements.push(translate_expr(expr))
end
istatements
end
# Testing Output
example = '((def x 10) (def y (* x 10)))'
puts example
puts ("token output: " << tokens(example).inspect)
puts ("parse output: " << parse(example).inspect)
puts ("translate output: " << translate(parse(example)).inspect)
# Putting together all the new source
c_src << include_macro
c_src << main_func_ent
c_src << " " << translate(parse(example)).join(" ")
# c_src << " " << translate(parse(lisp_src)).join(" ")
c_src << " " << main_func_ret
# Output C Source
puts '======= ACTUAL SOURCE ========='
puts c_src
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment