Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion lang/code/ast/common/func_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ var signatures = map[string]*FuncCallSignature{
"makeColor": makeSignature("makeColor", 1, ast.SignNumb),
"splitColor": makeSignature("splitColor", 1, ast.SignList),

"makeNdArray": makeSignature("makeNdArray", 2, ast.SignList),

"set": makeSignature("set", 4, ast.SignVoid),
"get": makeSignature("get", 3, ast.SignAny),
"call": makeSignature("call", -1-(3), ast.SignVoid),
Expand Down Expand Up @@ -180,17 +182,20 @@ func (f *FuncCall) Blockly(flags ...bool) ast.Block {
case "getPlainStartText":
return f.ctrlSimpleBlock("controls_getPlainStartText")
case "closeScreenWithPlainText":

return f.closeScreenWithPlainText()
case "copyList":
return f.copyList()
case "copyDict":
return f.copyDict()

case "makeColor":
return f.makeColor()
case "splitColor":
return f.splitColor()

case "makeNdArray":
return f.makeNdArray()

case "set":
return f.genericSet()
case "get":
Expand Down Expand Up @@ -318,6 +323,13 @@ func (f *FuncCall) genericSet() ast.Block {
}
}

func (f *FuncCall) makeNdArray() ast.Block {
return ast.Block{
Type: "matrices_create_multidim",
Values: ast.MakeValues(f.Args, "DIM", "INITIAL"),
}
}

func (f *FuncCall) splitColor() ast.Block {
return ast.Block{
Type: "color_make_color",
Expand Down
9 changes: 9 additions & 0 deletions lang/code/ast/common/question.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ func (q *Question) Blockly(flags ...bool) ast.Block {
return q.listQuestion()
case "dict":
return q.dictQuestion()
case "matrix":
return q.matrixQuestion()
case "emptyText":
return q.textIsEmpty()
case "emptyList":
Expand Down Expand Up @@ -89,6 +91,13 @@ func (q *Question) textIsEmpty() ast.Block {
}
}

func (q *Question) matrixQuestion() ast.Block {
return ast.Block{
Type: "matrices_is_matrix",
Values: []ast.Value{{Name: "VALUE", Block: q.On.Blockly(false)}},
}
}

func (q *Question) dictQuestion() ast.Block {
return ast.Block{
Type: "dictionaries_is_dict",
Expand Down
10 changes: 10 additions & 0 deletions lang/code/ast/method/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ var signatures = map[string]*CallSignature{
"keys": makeSignature("dict", "dictionaries_getters", 0, true, ast.SignList),
"values": makeSignature("dict", "dictionaries_getters", 0, true, ast.SignList),
"toPairs": makeSignature("dict", "dictionaries_dict_to_alist", 0, true, ast.SignList),

"row": makeSignature("matrix", "matrices_get_row", 1, true, ast.SignAny),
"col": makeSignature("matrix", "matrices_get_column", 1, true, ast.SignAny),
"dimension": makeSignature("matrix", "matrices_get_dims", 1, true, ast.SignList),
"inverse": makeSignature("matrix", "matrices_operations", 0, true, ast.SignList),
"transpose": makeSignature("matrix", "matrices_operations", 0, true, ast.SignList),
"rotateLeft": makeSignature("matrix", "matrices_operations", 0, true, ast.SignList),
"rotateRight": makeSignature("matrix", "matrices_operations", 0, true, ast.SignList),
}

func TestSignature(methodName string, argsCount int) (string, *CallSignature) {
Expand Down Expand Up @@ -133,6 +141,8 @@ func (c *Call) Blockly(flags ...bool) ast.Block {
return c.listMethods(signature)
case "dict":
return c.dictMethods(signature)
case "matrix":
return c.matrixMethods(signature)
default:
panic("Unknown module " + signature.Module)
}
Expand Down
60 changes: 60 additions & 0 deletions lang/code/ast/method/matrix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package method

import "Falcon/code/ast"

func (c *Call) matrixMethods(signature *CallSignature) ast.Block {
switch signature.BlocklyName {
case "matrices_get_row":
return c.matrixGetRow()
case "matrices_get_column":
return c.matrixGetColumn()
case "matrices_get_dims":
return c.matrixGetDimensions()
case "matrices_operations":
return c.matrixOperations()
default:
panic("Unknown matrix method: " + signature.BlocklyName)
}
}

func (c *Call) matrixOperations() ast.Block {
var blocklyOp string
switch c.Name {
case "inverse":
blocklyOp = "INVERSE"
case "transpose":
blocklyOp = "TRANSPOSE"
case "rotateLeft":
blocklyOp = "ROTATE_LEFT"
case "rotateRight":
blocklyOp = "ROTATE_RIGHT"
default:
panic("Unknown matrix operation: " + c.Name)
}
return ast.Block{
Type: "matrices_operations",
Fields: []ast.Field{{Name: "OP", Value: blocklyOp}},
Values: []ast.Value{{Name: "MATRIX", Block: c.On.Blockly()}},
}
}

func (c *Call) matrixGetDimensions() ast.Block {
return ast.Block{
Type: "matrices_get_dims",
Values: []ast.Value{{Name: "MATRIX", Block: c.On.Blockly()}},
}
}

func (c *Call) matrixGetRow() ast.Block {
return ast.Block{
Type: "matrices_get_row",
Values: ast.MakeValueArgs(c.On, "MATRIX", c.Args, "ROW"),
}
}

func (c *Call) matrixGetColumn() ast.Block {
return ast.Block{
Type: "matrices_get_column",
Values: ast.MakeValueArgs(c.On, "MATRIX", c.Args, "COLUMN"),
}
}
137 changes: 137 additions & 0 deletions lang/code/parsers/blocklytomist/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,34 @@ func (p *Parser) parseBlock(block ast.Block) ast.Expr {
case "math_convert_angles":
return p.mathConvertAngles(block)

case "matrices_create": // todo: we need to be able to form the matrix block from syntax (currently can't!, only lists)
return p.matricesCreate(block)
case "matrices_create_multidim":
return p.matricesNdArray(block)
case "matrices_get_cell":
return p.matricesGetCell(block) // todo: same, we need to preserve matrix reconversion at the end using comment blocks
case "matrices_set_cell":
return p.matricesSetCell(block) // todo: same thing
case "matrices_get_row":
return p.matricesGetRow(block) // we are done
case "matrices_get_column":
return p.matricesGetColumn(block) // we are done
case "matrices_get_dims":
return p.matricesGetDimension(block) // we are done
case "matrices_is_matrix":
return p.makeQuestion(lex.OpenSquare, block, "matrix")
case "matrices_add":
return p.makeBinary("+", p.fromMinVals(block.Values, 2))
case "matrices_subtract":
return p.makeBinary("-", p.fromMinVals(block.Values, 2))
case "matrices_multiply":
return p.makeBinary("*", p.fromMinVals(block.Values, 2))
case "matrices_power":
return p.makeBinary("^", p.fromMinVals(block.Values, 2))

case "matrices_operations":
return p.matricesOperations(block) // we are done

case "lists_create_with":
return &fundamentals.List{Elements: p.fromMinVals(block.Values, 0)}
case "lists_add_items":
Expand Down Expand Up @@ -947,6 +975,92 @@ func (p *Parser) textCompare(block ast.Block) ast.Expr {
return p.makeBinary(pOperation, p.fromMinVals(block.Values, 2))
}

func (p *Parser) matricesGetRow(block ast.Block) ast.Expr {
pVals := p.makeValueMap(block.Values)
return &method.Call{
Where: lex.MakeFakeToken(lex.OpenSquare),
On: pVals.get("MATRIX"),
Name: "row",
Args: []ast.Expr{pVals.get("ROW")},
}
}

func (p *Parser) matricesGetDimension(block ast.Block) ast.Expr {
pVals := p.makeValueMap(block.Values)
return &method.Call{
Where: lex.MakeFakeToken(lex.OpenSquare),
On: pVals.get("MATRIX"),
Name: "dimension",
Args: []ast.Expr{},
}
}

func (p *Parser) matricesGetColumn(block ast.Block) ast.Expr {
pVals := p.makeValueMap(block.Values)
return &method.Call{
Where: lex.MakeFakeToken(lex.OpenSquare),
On: pVals.get("MATRIX"),
Name: "col",
Args: []ast.Expr{pVals.get("COLUMN")},
}
}

func (p *Parser) matricesSetCell(block ast.Block) ast.Expr {
numItems := block.Mutation.ItemCount
pVals := p.makeValueMap(block.Values)

matrix := pVals.get("MATRIX")
var currHead ast.Expr
currHead = matrix

for i := 0; i < numItems-1; i++ {
dim := pVals.get("DIM" + strconv.Itoa(i))
currHead = &list.Get{List: currHead, Index: dim}
}
return &list.Set{List: currHead, Index: pVals.get("DIM" + strconv.Itoa(numItems-1)), Value: pVals.get("VALUE")}
}

func (p *Parser) matricesGetCell(block ast.Block) ast.Expr {
numItems := block.Mutation.ItemCount
pVals := p.makeValueMap(block.Values)

matrix := pVals.get("MATRIX")
var currHead ast.Expr
currHead = matrix

for i := 0; i < numItems; i++ {
dim := pVals.get("DIM" + strconv.Itoa(i))
currHead = &list.Get{List: currHead, Index: dim}
}
return currHead
}

func (p *Parser) matricesNdArray(block ast.Block) ast.Expr {
pVals := p.makeValueMap(block.Values)
return common.MakeFuncCall("makeNdArray", pVals.get("DIM"), pVals.get("INITIAL"))
}

func (p *Parser) matricesCreate(block ast.Block) ast.Expr {
pFields := p.makeFieldMap(block.Fields)
numRows, err := strconv.Atoi(pFields["ROWS"])
if err != nil {
panic(err)
}
numCols, err := strconv.Atoi(pFields["COLS"])
if err != nil {
panic(err)
}
matrix := make([]ast.Expr, numRows)
for i := range matrix {
row := make([]ast.Expr, numCols)
for j := range row {
row[j] = &fundamentals.Number{Content: pFields["MATRIX_"+strconv.Itoa(i)+"_"+strconv.Itoa(j)]}
}
matrix[i] = &fundamentals.List{Elements: row}
}
return &fundamentals.List{Elements: matrix}
}

func (p *Parser) mathConvertAngles(block ast.Block) ast.Expr {
var funcName string
switch block.SingleField() {
Expand Down Expand Up @@ -1093,6 +1207,29 @@ func (p *Parser) makeColor(block ast.Block) ast.Expr {
return &fundamentals.Color{Where: lex.MakeFakeToken(lex.ColorCode), Hex: block.SingleField()}
}

func (p *Parser) matricesOperations(block ast.Block) ast.Expr {
var matrixMethod string
switch block.SingleField() {
case "INVERSE":
matrixMethod = "inverse"
case "TRANSPOSE":
matrixMethod = "transpose"
case "ROTATE_LEFT":
matrixMethod = "rotateLeft"
case "ROTATE_RIGHT":
matrixMethod = "rotateRight"
default:
panic("Unknown matrix operation type: " + block.SingleField())
}
pVals := p.makeValueMap(block.Values)
return &method.Call{
Where: lex.MakeFakeToken(lex.OpenSquare),
On: pVals.get("MATRIX"),
Name: matrixMethod,
Args: []ast.Expr{},
}
}

func (p *Parser) makeQuestion(t lex.Type, on ast.Block, name string) ast.Expr {
return &common.Question{Where: lex.MakeFakeToken(t), On: p.singleExpr(on), Question: name}
}
Expand Down
15 changes: 1 addition & 14 deletions testing/hi.mist
Original file line number Diff line number Diff line change
@@ -1,14 +1 @@
@Button { Button1 }
@Label { Label1 }

func main() {
println("Hello, World!")
println("Counter is currently: " _ this.counter)
}

global counter = 0

when Button1.Click {
this.counter = this.counter + 1
Label1.Text = counter
}
[[1, 2], [3, 4]].rotateLeft()