diff --git a/ast/antlr_ast.go b/ast/antlr_ast.go
new file mode 100644
index 0000000..9c817eb
--- /dev/null
+++ b/ast/antlr_ast.go
@@ -0,0 +1,45 @@
+package ast
+
+import (
+	"lang/parsing"
+	"strconv"
+)
+
+type CSTWalker struct {
+	parsing.BaselangParserVisitor
+}
+
+func (c *CSTWalker) VisitInteger(ctx *parsing.IntegerContext) Integer {
+	val, _ := strconv.Atoi(ctx.INTEGER().GetText())
+	return Integer{val}
+}
+
+func (c *CSTWalker) VisitSum(ctx *parsing.SumContext) Infix {
+	return Infix{"+", c.Visit(ctx.Exp(0)), c.Visit(ctx.Exp(1))}
+}
+
+func (c *CSTWalker) VisitProduct(ctx *parsing.ProductContext) Infix {
+	return Infix{"*", c.Visit(ctx.Exp(0)), c.Visit(ctx.Exp(1))}
+}
+
+func (c *CSTWalker) VisitParens(ctx *parsing.ParensContext) interface{} {
+	return c.Visit(ctx.Exp())
+}
+
+func (c *CSTWalker) VisitIdent(ctx *parsing.IdentContext) Identifier {
+	return Identifier{ctx.IDENTIFIER().GetText()}
+}
+
+func (c *CSTWalker) VisitReal(ctx *parsing.RealContext) Real {
+	val, _ := strconv.ParseFloat(ctx.REAL().GetText(), 64)
+	return Real{val}
+}
+
+func (c *CSTWalker) VisitLet_statement(ctx *parsing.Let_statementContext) LetStatement {
+	return LetStatement{ctx.IDENTIFIER(0).GetText(), ctx.IDENTIFIER(1).GetText(), c.Visit(ctx.Exp())}
+}
+
+func (c *CSTWalker) VisitProgram(ctx *parsing.ProgramContext) Program {
+	list := make([]interface{}, 0)
+	return Program{list}
+}
diff --git a/ast/ast.go b/ast/ast.go
new file mode 100644
index 0000000..6c96233
--- /dev/null
+++ b/ast/ast.go
@@ -0,0 +1,29 @@
+package ast
+
+type Identifier struct {
+	val string
+}
+
+type Infix struct {
+	op  string
+	lhs interface{}
+	rhs interface{}
+}
+
+type Integer struct {
+	val int
+}
+
+type LetStatement struct {
+	kind string
+	name string
+	val  interface{}
+}
+
+type Program struct {
+	sentences []interface{}
+}
+
+type Real struct {
+	val float64
+}