Created
January 27, 2015 20:48
-
-
Save sdimitro/d5dc8bd844c4e7d85d45 to your computer and use it in GitHub Desktop.
Rudimentary lisp to C translation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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