Skip to content

Commit 2c7533e

Browse files
committed
Implement table name resolution across compiler, CG and bytecode
1 parent fd9dd22 commit 2c7533e

File tree

4 files changed

+60
-23
lines changed

4 files changed

+60
-23
lines changed

compiler/codegen/generator.go

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,27 @@ import (
1919
"github.com/RohitAwate/commaql/compiler/ast"
2020
"github.com/RohitAwate/commaql/compiler/common"
2121
"github.com/RohitAwate/commaql/compiler/parser/tokenizer"
22+
"github.com/RohitAwate/commaql/table"
2223
"github.com/RohitAwate/commaql/vm"
2324
"github.com/RohitAwate/commaql/vm/values"
2425
)
2526

2627
type CodeGenerator struct {
27-
statements []ast.Stmt
28-
Code vm.Bytecode
29-
Errors []common.Error
28+
statements []ast.Stmt
29+
Code vm.Bytecode
30+
Errors []common.Error
31+
tableContext map[string]*table.Table
3032
}
3133

32-
func NewCodeGenerator(statements []ast.Stmt) (*CodeGenerator, error) {
34+
func NewCodeGenerator(statements []ast.Stmt, tableContext map[string]*table.Table) (*CodeGenerator, error) {
3335
if statements == nil {
3436
return nil, fmt.Errorf("root of AST cannot be nil")
3537
}
3638

3739
return &CodeGenerator{
38-
statements: statements,
39-
Code: vm.NewBytecode(),
40+
statements: statements,
41+
Code: vm.NewBytecode(),
42+
tableContext: tableContext,
4043
}, nil
4144
}
4245

@@ -53,11 +56,15 @@ func (cg *CodeGenerator) Run() common.PhaseStatus {
5356

5457
func (cg *CodeGenerator) visitSelectStmt(ss *ast.SelectStmt) {
5558
for _, tableNode := range ss.Tables {
56-
val := values.String{Meta: tableNode.TableToken.Lexeme}
57-
loc := cg.Code.AddConstant(val)
58-
59-
cg.Code.EmitWithArg(vm.OpLoadConst, loc)
60-
cg.Code.Emit(vm.OpLoadTable)
59+
if resolvedTable, ok := cg.tableContext[tableNode.TableToken.Lexeme]; !ok {
60+
cg.emitError(fmt.Sprintf("unknown table: %s", tableNode.TableToken.Lexeme), tableNode.TableToken)
61+
return
62+
} else {
63+
loc := cg.Code.AddTableContext(resolvedTable)
64+
var tableRegisterIndex uint = 1 // TODO: make this dynamic for a pair of tables at a time
65+
cg.Code.EmitWithArgs(vm.OpLoadTable, loc, tableRegisterIndex)
66+
cg.Code.Emit(vm.OpLoadTable)
67+
}
6168
}
6269

6370
cg.Code.Emit(vm.OpSetExecCtx)
@@ -98,17 +105,17 @@ func (cg *CodeGenerator) visitLiteral(lit *ast.Literal) {
98105
// TODO: Write a helper for this, lots of duplication between these cases
99106
val := values.NewNumber(lit.Meta.Lexeme)
100107
loc := cg.Code.AddConstant(val)
101-
cg.Code.EmitWithArg(vm.OpLoadConst, loc)
108+
cg.Code.EmitWithArgs(vm.OpLoadConst, loc)
102109
case tokenizer.TRUE:
103110
fallthrough
104111
case tokenizer.FALSE:
105112
val := values.NewBoolean(lit.Meta.Type)
106113
loc := cg.Code.AddConstant(val)
107-
cg.Code.EmitWithArg(vm.OpLoadConst, loc)
114+
cg.Code.EmitWithArgs(vm.OpLoadConst, loc)
108115
case tokenizer.STRING:
109116
val := values.NewString(lit.Meta.Lexeme)
110117
loc := cg.Code.AddConstant(val)
111-
cg.Code.EmitWithArg(vm.OpLoadConst, loc)
118+
cg.Code.EmitWithArgs(vm.OpLoadConst, loc)
112119
default:
113120
// FIXME
114121
}
@@ -148,3 +155,7 @@ func (cg *CodeGenerator) visitBinaryExpr(be *ast.BinaryExpr) {
148155
func (cg *CodeGenerator) visitGroupedExpr(ge *ast.GroupedExpr) {
149156
cg.visitExpr(&ge.InnerExpr)
150157
}
158+
159+
func (cg *CodeGenerator) emitError(msg string, token common.Token) {
160+
cg.Errors = append(cg.Errors, common.Error{Message: msg, Location: token.Location})
161+
}

compiler/compiler.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
)
2626

2727
type Compiler struct {
28-
Tables []table.Table
28+
tableContext map[string]*table.Table
2929
}
3030

3131
func NewCompiler(filepath string) (*Compiler, error) {
@@ -34,12 +34,16 @@ func NewCompiler(filepath string) (*Compiler, error) {
3434
return nil, fmt.Errorf("file not found: %s", filepath)
3535
}
3636

37-
csvTable, err := table.NewCSVTable(reader)
37+
var csvTable table.Table
38+
csvTable, err = table.NewCSVTable(reader)
3839
if err != nil {
3940
return nil, fmt.Errorf("could not read from file: %s", filepath)
4041
}
4142

42-
return &Compiler{Tables: []table.Table{csvTable}}, nil
43+
tableContext := map[string]*table.Table{
44+
"superhero": &csvTable, // TODO: Remove hardcoded value
45+
}
46+
return &Compiler{tableContext: tableContext}, nil
4347
}
4448

4549
func (c *Compiler) Compile(query string) {
@@ -49,8 +53,14 @@ func (c *Compiler) Compile(query string) {
4953
p := parser.Parser{Tokens: tokens}
5054
statements, _ := p.Run()
5155

52-
cg, _ := codegen.NewCodeGenerator(statements)
56+
cg, _ := codegen.NewCodeGenerator(statements, c.tableContext)
5357
cg.Run()
5458

59+
if len(cg.Errors) > 0 {
60+
for _, err := range cg.Errors {
61+
fmt.Println(err.Message)
62+
}
63+
}
64+
5565
disassembler.Disassemble(&cg.Code)
5666
}

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func main() {
2424
amount,
2525
payment_date
2626
FROM
27-
customer
27+
superhero
2828
WHERE amount = 100 - 2
2929
ORDER BY payment_date, amount;`
3030

vm/bytecode.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414

1515
package vm
1616

17-
import "github.com/RohitAwate/commaql/vm/values"
17+
import (
18+
"github.com/RohitAwate/commaql/table"
19+
"github.com/RohitAwate/commaql/vm/values"
20+
)
1821

1922
type OpCode uint
2023

@@ -72,6 +75,7 @@ func GetOpCodeInfo(opCode OpCode) OpCodeInfo {
7275
type Bytecode struct {
7376
Blob []OpCode
7477
ConstantsPool []values.Value
78+
TableContext []*table.Table
7579
}
7680

7781
func NewBytecode() Bytecode {
@@ -86,12 +90,24 @@ func (b *Bytecode) AddConstant(v values.Value) uint {
8690
return uint(len(b.ConstantsPool) - 1)
8791
}
8892

93+
func (b *Bytecode) AddTableContext(t *table.Table) uint {
94+
b.TableContext = append(b.TableContext, t)
95+
return uint(len(b.TableContext) - 1)
96+
}
97+
8998
func (b *Bytecode) Emit(oc OpCode) uint {
9099
b.Blob = append(b.Blob, oc)
91100
return uint(len(b.Blob))
92101
}
93102

94-
func (b *Bytecode) EmitWithArg(oc OpCode, arg uint) uint {
95-
b.Blob = append(b.Blob, oc, OpCode(arg))
96-
return uint(len(b.Blob) - 2)
103+
func (b *Bytecode) EmitWithArgs(oc OpCode, args ...uint) uint {
104+
convertedArgs := make([]OpCode, len(args)+1)
105+
106+
convertedArgs[0] = oc
107+
for i, arg := range args {
108+
convertedArgs[i+1] = OpCode(arg)
109+
}
110+
111+
b.Blob = append(b.Blob, convertedArgs...)
112+
return uint(len(b.Blob) - len(convertedArgs))
97113
}

0 commit comments

Comments
 (0)