Skip to content

Instantly share code, notes, and snippets.

@ldfallas
Created December 1, 2009 11:43
Show Gist options
  • Save ldfallas/246239 to your computer and use it in GitHub Desktop.
Save ldfallas/246239 to your computer and use it in GitHub Desktop.
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