Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
Signed-off-by: George Lemon <[email protected]>
  • Loading branch information
georgelemon committed Aug 20, 2023
1 parent 7ba6bcb commit 78e976e
Show file tree
Hide file tree
Showing 17 changed files with 188 additions and 104 deletions.
2 changes: 1 addition & 1 deletion src/bropkg/engine/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ type
comment*: string
of ntVariable:
varName*: string
varValue*: Node
varValue*, varMod*: Node
varMeta*: Meta
varType*, varInitType*: NodeType
varUsed*, varArg*, varImmutable*,
Expand Down
92 changes: 53 additions & 39 deletions src/bropkg/engine/compiler.nim
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ template exploreAst =
else: "VarDef"
else: $(node.nt)
add info, "[$1:$2]" % [$(node.meta.line), $(node.meta.pos)]
echo indent(info, node.meta.pos)
# echo indent(info, node.meta.pos)

macro newHandler(name: static string, body: untyped) =
newProc(ident(name),
Expand Down Expand Up @@ -149,16 +149,16 @@ proc getTypeInfo(node: Node): string =
of ntAccessor:
add result, getTypeInfo(node.callNode.accessorStorage)
of ntVariable:
case node.callNode.varValue.nt:
case node.callNode.varMod.nt:
of ntArray:
# todo handle types of array (string, int, or mix for mixed values)
add result, "$1[$2]($3)" % [$(node.callNode.varValue.nt),
"mix", $(node.callNode.varValue.arrayItems.len)]
add result, "$1[$2]($3)" % [$(node.callNode.varMod.nt),
"mix", $(node.callNode.varMod.arrayItems.len)]
of ntObject:
add result, "$1($2)" % [$(node.callNode.varValue.nt),
$(node.callNode.varValue.pairsVal.len)]
add result, "$1($2)" % [$(node.callNode.varMod.nt),
$(node.callNode.varMod.pairsVal.len)]
else:
add result, "$1[$2]" % [$ntVariable, $(node.callNode.varValue.nt)]
add result, "$1[$2]" % [$ntVariable, $(node.callNode.varMod.nt)]
else: discard
else: discard
of ntString:
Expand All @@ -176,7 +176,7 @@ proc getTypeInfo(node: Node): string =
of ntAccessor:
add result, getTypeInfo(node.accessorStorage)
of ntVariable:
add result, getTypeInfo(node.varValue)
add result, getTypeInfo(node.varMod)
else: discard

proc sizeString(v: Node): string =
Expand All @@ -202,7 +202,7 @@ proc dumpHook*(s: var string, v: Node) =
of ntArray:
s.dumpHook(v.arrayItems)
of ntVariable:
s.dumpHook(v.varValue)
s.dumpHook(v.varMod)
else: discard

proc dumpHook*(s: var string, v: seq[Node]) =
Expand Down Expand Up @@ -543,9 +543,8 @@ proc walkAccessorStorage(c: Compiler, node, index: Node, scope: var seq[ScopeTab
except FieldDefect:
compileErrorWithArgs(invalidAccessorStorage, [index.toString])
of ntVariable:
# echo scope.hasKey(node.varName)
var varNode = c.scoped(node.varName, scope)
return c.walkAccessorStorage(varNode.varValue, index, scope)
return c.walkAccessorStorage(varNode.varMod, index, scope)
of ntStream:
case node.streamContent.kind:
of JObject:
Expand Down Expand Up @@ -573,15 +572,14 @@ proc nodeEvaluator(c: Compiler, node: Node, scope: var seq[ScopeTable]): Node =
of ntAccessor:
# node.callNode.accessorStorage = varNode.varValue
var x = c.walkAccessorStorage(node.callNode.accessorStorage,
node.callNode.accessorKey, scope)
node.callNode.accessorKey, scope)
if likely(x != nil):
return x
# return varNode.varValue
echo $invalidAccessorStorage
# compileErrorWithArgs(invalidAccessorStorage)
else:
return varNode.varValue
else: return varNode.varValue
return varNode.varMod
else: return varNode.varMod
compileErrorWithArgs(undeclaredVariable, [node.callIdent], node.meta)
of ntInfix:
return ast.newBool(c.infixEvaluator(node.infixLeft, node.infixRight, node.infixOp, scope))
Expand Down Expand Up @@ -620,8 +618,8 @@ proc nodeEvaluator(c: Compiler, node: Node, scope: var seq[ScopeTable]): Node =
result = node
of ntCallFunction:
return runCallable()
of ntForStmt:
echo node
# of ntForStmt:
# echo node
# of ntDotExpr:
# var lht: Node
# case node.dotLeft.nt:
Expand All @@ -640,7 +638,7 @@ newHandler "varAssignment":
#[
Handles variable assignments.
Bro has a strict type system, meaning that a string var
Bro has a strong type system, meaning that a string var
cannot be changed to `int`, `float`, `bool`, `size` (and so on)
once initialized.
Expand All @@ -649,10 +647,10 @@ newHandler "varAssignment":
let scopeVar = c.scoped(node.asgnVarIdent, scope)
if likely(scopeVar != nil):
let
varType = scopeVar.varValue.getNodeType
varType = scopeVar.varMod.getNodeType
varModifier = c.nodeEvaluator(node.asgnVal, scope)
if likely(varType == varModifier.nt):
scopeVar.varValue = varModifier
scopeVar.varMod = varModifier
return
compileErrorWithArgs(fnMismatchParam, [scopeVar.varName, $varModifier.nt, $varType], node.asgnVal.meta)
compileErrorWithArgs(undeclaredVariable, [node.asgnVarIdent], node.meta)
Expand All @@ -670,7 +668,11 @@ newHandler "varDefinition":
Note: Global variables are publicly visible (at least for now)
]#
if likely(inScope(node.varName, scope) == false):
node.varValue = c.nodeEvaluator(node.varValue, scope)
# case node.varValue.nt:
# of ntMathStmt:
node.varMod = c.nodeEvaluator(node.varValue, scope)
# else:
# node.varMod = c.nodeEvaluator(node.varValue, scope)
c.stack(node, scope)
return
compileErrorWithArgs(varRedefine, [node.varName], node.meta)
Expand All @@ -691,12 +693,18 @@ newHandler "command":
let meta = " (" & $(node.meta.line) & ":" & $(node.meta.pos) & ") "
let valNode: Node = c.nodeEvaluator(node.cmdValue, scope)
if likely(valNode != nil):
let valNodeStr =
case valNode.nt
of ntMathStmt:
valNode.mathResult
else:
valNode
# echo valNode.toString
stdout.styledWriteLine(
fgGreen, "Debug",
fgDefault, meta,
fgMagenta, getTypeInfo(valNode),
fgDefault, "\n" & valNode.toString
fgDefault, "\n" & valNodeStr.toString
)
of cmdAssert:
if c.infixEvaluator(node.cmdValue.infixLeft, node.cmdValue.infixRight,
Expand Down Expand Up @@ -743,11 +751,11 @@ newHandler "forBlock":
case itemsNode.nt
of ntArray:
let len = itemsNode.arrayItems.len
for item in 0 .. itemsNode.arrayItems.high:
for item in itemsNode.arrayItems:
var forScope = ScopeTable()
forScope[node.forItem[0].varName] = node.forItem[0]
forScope[node.forItem[0].varName].varMod = item
add scope, forScope
forScope[node.forItem[0].varName].varValue = itemsNode.arrayItems[item]
for innerNode in node.forBody.stmtList:
c.handleInnerNode(innerNode, parent, scope, len, ix)
scope.delete(scope.high) # out of scope
Expand All @@ -758,9 +766,9 @@ newHandler "forBlock":
for k, v in itemsNode.pairsVal:
var forScope = ScopeTable()
forScope[node.forItem[0].varName] = node.forItem[0]
forScope[node.forItem[0].varName].varValue = ast.newString(k)
forScope[node.forItem[0].varName].varMod = ast.newString(k)
forScope[node.forItem[1].varName] = node.forItem[1]
forScope[node.forItem[1].varName].varValue = v
forScope[node.forItem[1].varName].varMod = v
add scope, forScope
for innerNode in node.forBody.stmtList:
c.handleInnerNode(innerNode, parent, scope, len, ix)
Expand All @@ -770,19 +778,24 @@ newHandler "forBlock":
for k in keys(itemsNode.pairsVal):
var forScope = ScopeTable()
forScope[node.forItem[0].varName] = node.forItem[0]
forScope[node.forItem[0].varName].varvalue = ast.newString(k)
forScope[node.forItem[0].varName].varMod = ast.newString(k)
add scope, forScope
for innerNode in node.forBody.stmtList:
c.handleInnerNode(innerNode, parent, scope, len, ix)
scope.delete(scope.high)
of ntStream:
case itemsNode.streamContent.kind
of JArray:
if unlikely(node.forItem[1] != nil):
compileErrorWithArgs(forInvalidIteration)
let len = node.forBody.stmtList.len
for item in items(itemsNode.streamContent):
var forScope = ScopeTable()
forScope[node.forItem[0].varName] = node.forItem[0]
forScope[node.forItem[0].varName].varValue = newStream item
forScope[node.forItem[0].varName].varMod =
case item.kind
of JArray, JObject: newStream(item)
else: item.toNode
add scope, forScope
for innerNode in node.forBody.stmtList:
c.handleInnerNode(innerNode, parent, scope, len, ix)
Expand All @@ -794,9 +807,12 @@ newHandler "forBlock":
for k, v in pairs(itemsNode.streamContent):
var forScope = ScopeTable()
forScope[node.forItem[0].varName] = node.forItem[0]
forScope[node.forItem[0].varName].varValue = ast.newString(k)
forScope[node.forItem[0].varName].varMod = ast.newString(k)
forScope[node.forItem[1].varName] = node.forItem[1]
forScope[node.forItem[1].varName].varValue = ast.newStream(v)
forScope[node.forItem[1].varName].varMod =
case v.kind
of JArray, JObject: newStream(v)
else: v.toNode
add scope, forScope
for innerNode in node.forBody.stmtList:
c.handleInnerNode(innerNode, parent, scope, len, ix)
Expand All @@ -806,16 +822,14 @@ newHandler "forBlock":
for k in keys(itemsNode.streamContent):
var forScope = ScopeTable()
forScope[node.forItem[0].varName] = node.forItem[0]
forScope[node.forItem[0].varName].varValue = ast.newString(k)
forScope[node.forItem[0].varName].varMod = ast.newString(k)
add scope, forScope
for innerNode in node.forBody.stmtList:
c.handleInnerNode(innerNode, parent, scope, len, ix)
scope.delete(scope.high)
else: compileErrorWithArgs(forInvalidIteration, node.meta)
else: compileErrorWithArgs(forInvalidIterationGot, [$(itemsNode.nt)], node.meta)
else:
echo node
echo "invalid iteration"
else: compileErrorWithArgs(forInvalidIterationGot, ["null"], node.meta)

newHandler "importModule":
#[
Expand Down Expand Up @@ -893,8 +907,8 @@ proc handleInnerNode(c: Compiler, node, parent: Node,
if unlikely(node.pseudo.len > 0):
for k, psNode in node.pseudo:
add c.deferred, c.getSelectorGroup(psNode, scope, node)
of ntVariable: c.varDefinition(node, scope, parent)
of ntAssign: c.varAssignment(node, scope, parent)
of ntVariable: c.varDefinition(node, scope, parent)
of ntAssign: c.varAssignment(node, scope, parent)
of ntCallFunction: c.fnCallVoid(node, scope)
of ntFunction: c.fnDefinition(node, scope)
of ntCommand: c.command(node, scope)
Expand Down Expand Up @@ -926,9 +940,9 @@ proc getSelectorGroup(c: Compiler, node: Node,
# .my, .second, .selector
add result, "," & node.extendBy.join(", ")
for concatVar in node.identConcat:
var varValue = c.nodeEvaluator(concatVar, scope)
if likely(varValue != nil):
add result, varValue.toString
var varMod = c.nodeEvaluator(concatVar, scope)
if likely(varMod != nil):
add result, varMod.toString
else: break
add result, c.strCL # {
for pName in node.properties.keys:
Expand Down
2 changes: 1 addition & 1 deletion src/bropkg/engine/handlers/pAssignment.nim
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ proc parseAssignment(p: var Parser, ident: TokenTuple, varTypeDecl: TokenKind):
if likely(varDef != nil):
let varValue = p.getPrefixOrInfix()
if likely(varValue != nil):
varDef.varType = varValue.getNodeType
# varDef.varType = varValue.getNodeType
varDef.varValue = varValue
return varDef
let varValue = p.getPrefixOrInfix()
Expand Down
2 changes: 1 addition & 1 deletion src/bropkg/engine/stdlib.nim
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ macro initStdlib() =
if not isAbsolute(args[0].value.sVal):
absolutePath(args[0].value.sVal)
else: args[0].value.sVal
let str = readFile(args[0].value.sVal)
let str = readFile(filepath)
let ext = filepath.splitFile.ext
if ext == ".json":
return ast.newStream(str.fromJson(JsonNode))
Expand Down
16 changes: 16 additions & 0 deletions tests/stylesheets/basic.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.btn {
background-color: #FFFFFF;
border-color: #DBDBDB;
border-width: 1px;
color: #363636;
cursor: pointer;
justify-content: center;
padding: 10px 14px;
text-align: center;
white-space: nowrap
}
.btn .is-black {
background-color: #0A0A0A;
border-color: transparent;
color: #FFFFFF
}
11 changes: 7 additions & 4 deletions tests/stylesheets/for.bass
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
var colors = [blue, yellow, pink, green]
import std/colors
var someArray = ["red", "green", "blue"]
for $str in $someArray:
var x = parseColor($str)
.btn-{$str}
background-color: $x

for $color in $colors:
.btn-{$color}
color: $color
assert parseColor($someArray[0]) == toHex(red)
5 changes: 0 additions & 5 deletions tests/stylesheets/forjson.bass

This file was deleted.

3 changes: 1 addition & 2 deletions tests/stylesheets/invalid.bass
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
.element
fontsize: 12px
echo $x
10 changes: 10 additions & 0 deletions tests/stylesheets/json.bass
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import std/colors

var stream = json("./tests/stylesheets/sample.json")

for $str in $stream:
var x = parseColor($str)
.btn-{$str}
background-color: $x

assert parseColor($stream[0]) == toHex(red)
4 changes: 1 addition & 3 deletions tests/stylesheets/sample.json
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
{
"colors": ["yellow", "blue", "pink"]
}
["red", "green", "blue"]
1 change: 1 addition & 0 deletions tests/stylesheets/test_arrays.bass
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ $x.shift()
assert $x.contains("red") == false

$x.shuffle()
echo $x
17 changes: 14 additions & 3 deletions tests/stylesheets/test_colors.bass
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import std/colors

var strColors = json("sample.json")
var strColors = json("./tests/stylesheets/sample.json")
echo $strColors

assert parseColor($strColors["colors"][1]) == blue
assert parseColor($strColors[1]) == green
assert toHex(white) == #FFFFFF
assert rgb(255,255,255) == white

Expand All @@ -12,4 +12,15 @@ echo lighten($bluez, 20%)
echo darken($bluez, 20%)

echo saturate($bluez, 100%)
echo desaturate($bluez, 100%)
echo desaturate($bluez, 100%)

const stream = json("./tests/stylesheets/colors.json")
for $k, $v in $stream:
.bg-{$k}
background: parseColor($v)
assert parseColor($k) == parseColor($v)

// parse some colors
assert parseColor($stream["aliceblue"]) == toHex(aliceblue)
assert parseColor($stream["coral"]) == #ff7f50
assert parseColor($stream["gainsboro"]) == #dcdcdc
Loading

0 comments on commit 78e976e

Please sign in to comment.