Skip to content

Commit

Permalink
implemented constant expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
Glowman554 committed May 27, 2024
1 parent 475ea55 commit 5eab5e4
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 6 deletions.
70 changes: 70 additions & 0 deletions fire/firestorm/constexpr/constexpr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package constexpr

import (
"fire/firestorm/parser"
"strconv"
)

func boolToInt(v bool) int {
if v {
return 1
}
return 0
}

func Evaluate(node *parser.Node) int {
switch node.Type {
case parser.NUMBER:
return node.Value.(int)
case parser.ADD:
return Evaluate(node.A) + Evaluate(node.B)
case parser.SUBTRACT:
return Evaluate(node.A) - Evaluate(node.B)
case parser.MULTIPLY:
return Evaluate(node.A) * Evaluate(node.B)
case parser.DIVIDE:
return Evaluate(node.A) - Evaluate(node.B)
case parser.PLUS:
return +Evaluate(node.A)
case parser.MINUS:
return -Evaluate(node.A)
case parser.MODULO:
return Evaluate(node.A) % Evaluate(node.B)
case parser.COMPARE:
switch node.Value.(parser.Compare) {
case parser.More:
return boolToInt(Evaluate(node.A) > Evaluate(node.B))
case parser.Less:
return boolToInt(Evaluate(node.A) < Evaluate(node.B))
case parser.MoreEquals:
return boolToInt(Evaluate(node.A) >= Evaluate(node.B))
case parser.LessEquals:
return boolToInt(Evaluate(node.A) <= Evaluate(node.B))
case parser.Equals:
return boolToInt(Evaluate(node.A) == Evaluate(node.B))
case parser.NotEquals:
return boolToInt(Evaluate(node.A) != Evaluate(node.B))
}
panic("?")
case parser.NOT:
if Evaluate(node.A) == 0 {
return 1
} else {
return 0
}
case parser.SHIFT_LEFT:
return Evaluate(node.A) << Evaluate(node.B)
case parser.SHIFT_RIGHT:
return Evaluate(node.A) >> Evaluate(node.B)
case parser.AND:
return Evaluate(node.A) & Evaluate(node.B)
case parser.OR:
return Evaluate(node.A) | Evaluate(node.B)
case parser.XOR:
return Evaluate(node.A) ^ Evaluate(node.B)
case parser.BIT_NOT:
return ^Evaluate(node.A)
default:
panic(strconv.Itoa(int(node.Type)) + " not supported in contant expression")
}
}
3 changes: 1 addition & 2 deletions fire/firestorm/parser/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const (
PLUS
MINUS
MODULO
POWER
VARIABLE_LOOKUP
VARIABLE_LOOKUP_ARRAY

Expand Down Expand Up @@ -64,4 +63,4 @@ func NewNode(nodeType NodeType, a *Node, b *Node, value any) *Node {
B: b,
Value: value,
}
}
}
9 changes: 6 additions & 3 deletions fire/firestorm/target/llvm/llvm.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package llvm

import (
"fire/firestorm/constexpr"
"fire/firestorm/parser"
"fire/firestorm/utils"
"fmt"
Expand Down Expand Up @@ -489,10 +490,12 @@ func (b *LLVM) Compile() string {
if tmp[i].A.Type == parser.STRING {
s := b.module.NewGlobalDef(datatype.Name+".init", constant.NewCharArrayFromString(tmp[i].A.Value.(string)+"\x00"))
global = b.module.NewGlobalDef(datatype.Name, constant.NewIntToPtr(constant.NewPtrToInt(s, types.I64), d))
} else if tmp[i].A.Type == parser.NUMBER {
global = b.module.NewGlobalDef(datatype.Name, constant.NewInt(d.(*types.IntType), int64(tmp[i].A.Value.(int))))
} else {
panic("Only string and number are supported for globals!")
if inttype, ok := d.(*types.IntType); ok {
global = b.module.NewGlobalDef(datatype.Name, constant.NewInt(inttype, int64(constexpr.Evaluate(tmp[i].A))))
} else {
panic("Expected int type when using constant expression")
}
}
} else {
switch d := d.(type) {
Expand Down
2 changes: 1 addition & 1 deletion libraries/stdlib/fire.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "stdlib",
"version": "1.0.4",
"version": "1.0.5",
"target": null
}
4 changes: 4 additions & 0 deletions libraries/stdlib/impl/io.fl
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ function printi_base(int num, int base) -> void {
function printi(int num) -> void {
printi_base(num, 10);
}

function printnl() -> void {
printc(10);
}
18 changes: 18 additions & 0 deletions validation/constexpr.fl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
$include <std.fl>

int g1 = 1 + 2 * 3;
int g2 = (1 + 2) * 3;
chr g3 = 'a' + 5;
int g4 = 1 > 2;
int g5 = 1 < 2;


function spark(int argc, str[] argv) -> int {
printi(g1);
printi(g2);
printc(g3);
printnl();
printi(g4);
printi(g5);
return 0;
}
5 changes: 5 additions & 0 deletions validation/constexpr.fl.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"arguments": [],
"output": ["7", "9", "f", "0", "1"],
"should_fail": false
}

0 comments on commit 5eab5e4

Please sign in to comment.