Created
December 1, 2009 11:43
-
-
Save ldfallas/246239 to your computer and use it in GitHub Desktop.
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
package main | |
import "fmt" | |
type Environment struct { | |
bindings map[string] SExp | |
} | |
func (e Environment) Lookup(name string) SExp { | |
var result SExp; | |
value,success := e.bindings[name]; | |
if (!success) { | |
fmt.Printf("1..."); | |
result = SExpSymbol("<NULL>") | |
} else { | |
fmt.Printf("2..."); | |
result = value | |
} | |
return result | |
} | |
func (e Environment) Bind(name string,value SExp) { | |
e.bindings[name] = value; | |
} | |
type SExp interface { | |
Evaluate(e Environment) SExp; | |
Apply(args SExpList ) (result SExp,success bool); | |
AsString() string; | |
} | |
type SExpNumber int | |
type SExpString string | |
type SExpSymbol string | |
type SExpList []SExp | |
type SExpFunc func(l SExpList) SExp | |
/// Number | |
func (this SExpNumber) Evaluate(e Environment) SExp { | |
return this; | |
} | |
func (this SExpNumber) Apply(args SExpList) (result SExp,success bool) { | |
success = false; | |
return | |
} | |
func (this SExpNumber) AsString() string { | |
return fmt.Sprintf("%d",this); | |
} | |
/// String | |
func (this SExpString) Evaluate(e Environment) SExp { | |
return this; | |
} | |
func (this SExpString) Apply(args SExpList) (result SExp,success bool) { | |
success = false; | |
return | |
} | |
func (this SExpString) AsString() string { | |
return fmt.Sprintf("\"%s\"",this); | |
} | |
/// Symbol | |
func (this SExpSymbol) Evaluate(e Environment) SExp { | |
return e.Lookup(string(this)); | |
} | |
func (this SExpSymbol) AsString() string { | |
return fmt.Sprintf("%s",this); | |
} | |
func (this SExpSymbol) Apply(args SExpList) (result SExp,success bool) { | |
success = false; | |
return | |
} | |
/// List | |
func (this SExpList) Evaluate(env Environment) SExp { | |
f := this[0].Evaluate(env); | |
args := make( []SExp, len(this) - 1); | |
for i,e := range(this) { | |
if (i > 0) { | |
args[i-1] = e.Evaluate(env); | |
} | |
} | |
fmt.Printf("1!!!\n"); | |
result,_ := f.Apply(args); | |
return result | |
} | |
func (this SExpList) Apply(args SExpList) (result SExp,success bool) { | |
success = false; | |
return | |
} | |
func (this SExpList) AsString() string { | |
var result string; | |
result = "("; | |
for _,e := range(this) { | |
result = result + e.AsString() + " " | |
} | |
result = result + ")"; | |
return result | |
} | |
/// SExp Func | |
func (this SExpFunc) Evaluate(e Environment) SExp { | |
return this | |
} | |
func (this SExpFunc) AsString() string { | |
return "<func>" | |
} | |
func (this SExpFunc) Apply(args SExpList) (result SExp,success bool) { | |
success = true; | |
result = this(args); | |
return | |
} | |
func main() { | |
x := new(int); | |
fmt.Printf("%d\n",*x); | |
*x = 2; | |
fmt.Printf("%d\n",*x); | |
var v SExp; | |
v = SExpNumber(4); | |
fmt.Printf("%d\n",v); | |
env := Environment {make(map[string] SExp)}; | |
env.Bind("+", | |
SExpFunc(func (args []SExp) SExp{ | |
fmt.Printf("2!!!\n"); | |
return SExpNumber(int(args[0].(SExpNumber)) + | |
int(args[1].(SExpNumber)))})); | |
list1 := SExpList( | |
[]SExp {SExpNumber(2), | |
SExpNumber(3), | |
SExpString("A"), | |
SExpNumber(5), | |
SExpString("dsf")}); | |
fmt.Printf("1 --> %s\n",list1.AsString()); | |
exp1 := SExpList( | |
[]SExp {SExpSymbol("+"), | |
SExpList( | |
[]SExp {SExpSymbol("+"), | |
SExpNumber(4), | |
SExpNumber(3)}), | |
SExpNumber(2)}); | |
fmt.Printf("2 --> %s\n",(exp1.Evaluate(env)).AsString()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment