Skip to content

Commit

Permalink
Add 'defined' keyword
Browse files Browse the repository at this point in the history
  • Loading branch information
bendmorris committed Mar 3, 2019
1 parent 7226ffb commit 4557d2b
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 10 deletions.
2 changes: 2 additions & 0 deletions src/Kit/Ast/ExprType.hs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ data ExprType a b
| StaticExpr a
| Yield a
| Tokens Str
| Defined (Identifier b)
deriving (Eq, Generic, Show)

instance (Hashable a, Hashable b) => Hashable (ExprType a b)
Expand Down Expand Up @@ -156,6 +157,7 @@ exprDiscriminant et = case et of
UnionInit _ _ -> 50
VarArgListCopy _ -> 51
StaticVtable _ -> 52
Defined _ -> 53
x -> throwk
$ InternalError ("Expression has no discriminant: " ++ show x) Nothing

Expand Down
14 changes: 7 additions & 7 deletions src/Kit/Ast/TypedExpr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ module Kit.Ast.TypedExpr (
makeBlock
) where

import Data.Hashable
import GHC.Generics
import Kit.Ast.ConcreteTypeBase
import Kit.Ast.Definitions
import Kit.Ast.ExprType
import Kit.Ast.Span
import Kit.Ast.Value
import Data.Hashable
import GHC.Generics
import Kit.Ast.ConcreteTypeBase
import Kit.Ast.Definitions
import Kit.Ast.ExprType
import Kit.Ast.Span
import Kit.Ast.Value

type ConcreteType = ConcreteTypeBase TypedExpr

Expand Down
3 changes: 3 additions & 0 deletions src/Kit/Compiler/Typers/ConvertExpr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ convertExpr ctx tctx mod params e = do
x <- r x
t <- mtv
return $ m (StaticExpr x) t
Defined id -> do
id <- convertIdentifier (\_ -> return TypeVoid) id
return $ m (Defined id) TypeBool
VarArgListCopy s -> do
return $ m (VarArgListCopy s) TypeVaList
_ -> throwk $ InternalError
Expand Down
7 changes: 7 additions & 0 deletions src/Kit/Compiler/Typers/TypeExpression.hs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,13 @@ typeExpr ctx tctx mod ex@(TypedExpr { tExpr = et, tPos = pos }) = do
("static expression couldn't be evaluated at compile time")
(tPos x)

(Defined (Var x)) -> do
binding <- lookupBinding ctx x
let val = BoolValue $ isJust binding
return $ (makeExprTyped (Literal val TypeBool) TypeBool pos) {
tCompileTimeValue = Just val
}

(EnumInit b _ _) -> do
resolve $ TypeEq
(inferredType ex)
Expand Down
1 change: 1 addition & 0 deletions src/Kit/Parser/Lexer.x
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ tokens :-
continue { tok KeywordContinue }
default { tok KeywordDefault }
defer { tok KeywordDefer }
defined { tok KeywordDefined }
do { tok KeywordDo }
else { tok KeywordElse }
empty { tok KeywordEmpty }
Expand Down
4 changes: 4 additions & 0 deletions src/Kit/Parser/Parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import Kit.Str
continue {(KeywordContinue,_)}
default {(KeywordDefault,_)}
defer {(KeywordDefer,_)}
defined {(KeywordDefined,_)}
do {(KeywordDo,_)}
else {(KeywordElse,_)}
empty {(KeywordEmpty,_)}
Expand Down Expand Up @@ -680,6 +681,9 @@ BaseExpr :: {Expr}
| '(' identifier "..." ')' {pe (snd $1 <+> snd $4) $ VarArgListCopy $ extract_identifier $2}
| unsafe Expr {pe (snd $1 <+> pos $2) (Unsafe $2)}
| sizeof TypeSpec {pe (snd $1 <+> snd $2) (SizeOf $ fst $2)}
| sizeof '(' TypeSpec ')' {pe (snd $1 <+> snd $3) (SizeOf $ fst $3)}
| defined Identifier {pe (snd $1 <+> snd $2) (Defined $ fst $2)}
| defined '(' Identifier ')' {pe (snd $1 <+> snd $3) (Defined $ fst $3)}
| '(' Expr ParenthesizedExprs ')' {if null $3 then $2 {pos = snd $1 <+> snd $4} else pe (snd $1 <+> snd $4) (TupleInit ($2 : reverse $3)) }
| null {pe (snd $1) Null}
| empty {pe (snd $1) Empty}
Expand Down
2 changes: 2 additions & 0 deletions src/Kit/Parser/Token.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ data TokenClass
| KeywordConst
| KeywordContinue
| KeywordDefault
| KeywordDefined
| KeywordDefer
| KeywordDo
| KeywordElse
Expand Down Expand Up @@ -140,6 +141,7 @@ instance Show TokenClass where
KeywordContinue -> "continue"
KeywordDefault -> "default"
KeywordDefer -> "defer"
KeywordDefined -> "defined"
KeywordDo -> "do"
KeywordElse -> "else"
KeywordEmpty -> "empty"
Expand Down
11 changes: 9 additions & 2 deletions std/kit/utils.kit
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@
// }

#[noreturn] function panic(msg: Const[CString], args...) {
vfprintf(stderr, msg, (args...));
fputs("", stderr);
static if defined stderr {
// use stderr in environments where it's defined
vfprintf(stderr, msg, (args...));
fputs("", stderr);
} else {
// fall back to stdout
vprintf(msg, (args...));
puts("");
}
abort();
}
4 changes: 3 additions & 1 deletion tests/Kit/Parser/LexerSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,16 @@ spec = parallel $ do
, (FunctionArrow, sp "" 1 7 1 8)
]
it "lexes keywords" $ do
lx "abstract inline for in public rule rules"
lx "abstract defined inline for in public rule rules undefined"
`shouldBe` [ KeywordAbstract
, KeywordDefined
, KeywordInline
, KeywordFor
, KeywordIn
, KeywordPublic
, KeywordRule
, KeywordRules
, KeywordUndefined
]
it "skips whitespace" $ do
lx2 " \t \n \r\t \na \n\n\n\t\t\t\r\n\r\n \r \n"
Expand Down
15 changes: 15 additions & 0 deletions tests/functional/defined.kit
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function main() {
var b = defined stdout;
puts(if b then "true" else "false");

static if defined stdout {
puts("stdout exists");
} else {
puts("stdout doesn't exist");
}
static if defined stdout123987 {
puts("stdout123987 exists");
} else {
puts("stdout123987 doesn't exist");
}
}
3 changes: 3 additions & 0 deletions tests/functional/defined.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
true
stdout exists
stdout123987 doesn't exist

0 comments on commit 4557d2b

Please sign in to comment.