@@ -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
2627type 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
5457func (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) {
148155func (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+ }
0 commit comments