Skip to content

Commit d56b49e

Browse files
authored
Merge pull request #1 from ThePat02/feat/logic
add: Variables and Logic
2 parents be611d7 + de603c0 commit d56b49e

File tree

8 files changed

+1127
-78
lines changed

8 files changed

+1127
-78
lines changed

examples/shop.q

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
LET shop_name = "The Enchanted Emporium"
2+
LET wallet = 50
3+
LET has_sinister_key = FALSE
4+
5+
RANDOM {
6+
{ SHOPKEEP: "Welcome! How can I help you today?" },
7+
{ SHOPKEEP: "Hello there! Looking for something special?" },
8+
{ SHOPKEEP: "Greetings! What brings you to my shop today?" }
9+
}
10+
11+
SYSTEM: "You enter {shop_name}!"
12+
13+
LABEL shop
14+
SYSTEM: "Wallet: {wallet} coins"
15+
CHOICE {
16+
"Sinister Key (30)" {
17+
IF wallet >= 30 {
18+
IF has_sinister_key {
19+
SHOPKEEP: "You already have a Sinister Key."
20+
GOTO shop
21+
}
22+
wallet -= 30
23+
has_sinister_key = TRUE
24+
} ELSE { GOTO insufficient_funds }
25+
},
26+
"Mystic Potion (20)" {
27+
IF wallet >= 20 {
28+
wallet -= 20
29+
} ELSE { GOTO insufficient_funds }
30+
},
31+
"Healing Herb (10)" {
32+
IF wallet >= 10 {
33+
wallet -= 10
34+
} ELSE { GOTO insufficient_funds }
35+
},
36+
"Goodbye!" { GOTO leave_shop }
37+
}
38+
39+
SHOPKEEP: "Thank you for your purchase! Is there anything else I can assist you with?"
40+
GOTO shop
41+
42+
LABEL leave_shop
43+
44+
RANDOM {
45+
{ SHOPKEEP: "Thank you for visiting! Come back soon!" },
46+
{ SHOPKEEP: "Take care! Hope to see you again!" },
47+
{ SHOPKEEP: "Farewell! Don't forget to tell your friends about us!" }
48+
}
49+
50+
END
51+
52+
LABEL insufficient_funds
53+
SHOPKEEP: "Oh, it seems you don't have enough coins for that item."
54+
GOTO shop

internal/ast/expressions.go

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ type Identifier struct {
99

1010
func (i *Identifier) expressionNode() {}
1111
func (i *Identifier) String() string {
12+
if i == nil {
13+
return "<nil Identifier>"
14+
}
1215
return i.Value
1316
}
1417

@@ -19,6 +22,9 @@ type StringLiteral struct {
1922

2023
func (sl *StringLiteral) expressionNode() {}
2124
func (sl *StringLiteral) String() string {
25+
if sl == nil {
26+
return "<nil StringLiteral>"
27+
}
2228
return "\"" + sl.Value + "\""
2329
}
2430

@@ -29,6 +35,9 @@ type TagList struct {
2935

3036
func (tl *TagList) expressionNode() {}
3137
func (tl *TagList) String() string {
38+
if tl == nil {
39+
return "<nil TagList>"
40+
}
3241
if len(tl.Tags) == 0 {
3342
return "[]"
3443
}
@@ -38,8 +47,109 @@ func (tl *TagList) String() string {
3847
if i > 0 {
3948
result += ", "
4049
}
41-
result += tag.String()
50+
if tag != nil {
51+
result += tag.String()
52+
}
4253
}
4354
result += "]"
4455
return result
4556
}
57+
58+
// Boolean Literal
59+
type BooleanLiteral struct {
60+
Token token.Token
61+
Value bool
62+
}
63+
64+
func (bl *BooleanLiteral) expressionNode() {}
65+
func (bl *BooleanLiteral) String() string {
66+
if bl == nil {
67+
return "<nil BooleanLiteral>"
68+
}
69+
return bl.Token.Lexeme
70+
}
71+
72+
// Integer Literal
73+
type IntegerLiteral struct {
74+
Token token.Token
75+
Value int64
76+
}
77+
78+
func (il *IntegerLiteral) expressionNode() {}
79+
func (il *IntegerLiteral) String() string {
80+
if il == nil {
81+
return "<nil IntegerLiteral>"
82+
}
83+
return il.Token.Lexeme
84+
}
85+
86+
// Infix Expression (for operators like +, -, ==, >=, etc.)
87+
type InfixExpression struct {
88+
Token token.Token // the operator token
89+
Left Expression
90+
Operator string
91+
Right Expression
92+
}
93+
94+
func (ie *InfixExpression) expressionNode() {}
95+
func (ie *InfixExpression) String() string {
96+
if ie == nil {
97+
return "<nil InfixExpression>"
98+
}
99+
result := "("
100+
if ie.Left != nil {
101+
result += ie.Left.String()
102+
}
103+
result += " " + ie.Operator + " "
104+
if ie.Right != nil {
105+
result += ie.Right.String()
106+
}
107+
result += ")"
108+
return result
109+
}
110+
111+
// Prefix Expression (for operators like !)
112+
type PrefixExpression struct {
113+
Token token.Token // the prefix token
114+
Operator string
115+
Right Expression
116+
}
117+
118+
func (pe *PrefixExpression) expressionNode() {}
119+
func (pe *PrefixExpression) String() string {
120+
if pe == nil {
121+
return "<nil PrefixExpression>"
122+
}
123+
result := "(" + pe.Operator
124+
if pe.Right != nil {
125+
result += pe.Right.String()
126+
}
127+
result += ")"
128+
return result
129+
}
130+
131+
// Variable Interpolation Expression (for {variable} in strings)
132+
type InterpolatedString struct {
133+
Token token.Token
134+
Parts []Expression // mix of StringLiteral and Identifier
135+
}
136+
137+
func (is *InterpolatedString) expressionNode() {}
138+
func (is *InterpolatedString) String() string {
139+
if is == nil {
140+
return "<nil InterpolatedString>"
141+
}
142+
result := "\""
143+
for _, part := range is.Parts {
144+
if part == nil {
145+
continue
146+
}
147+
if ident, ok := part.(*Identifier); ok {
148+
result += "{" + ident.String() + "}"
149+
} else {
150+
result += part.String()
151+
}
152+
}
153+
result += "\""
154+
return result
155+
}

internal/ast/node.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@ type Program struct {
1919
}
2020

2121
func (p *Program) String() string {
22+
if p == nil {
23+
return "<nil Program>"
24+
}
2225
var out string
2326
for _, stmt := range p.Statements {
24-
out += stmt.String() + "\n"
27+
if stmt != nil {
28+
out += stmt.String() + "\n"
29+
}
2530
}
2631
return out
2732
}

0 commit comments

Comments
 (0)