diff --git a/evaluator/prefix.go b/evaluator/prefix.go index f46ca91..c2d03af 100644 --- a/evaluator/prefix.go +++ b/evaluator/prefix.go @@ -37,6 +37,22 @@ func evalPrefixExpression(operator string, right object.Object, line int) object return evalMinusPrefixOperatorExpression(right, line) case "+": return evalPlusPrefixOperatorExpression(right, line) + case "*": + if right == nil { + return newError("Mstari %d: huwezi kufikia thamani ya pointer isiyo na kitu (nil)", line) + } + if p, ok := right.(*object.Pointer); ok { + if p.Ref == nil { + return newError("Mstari %d: pointer haina kitu (nil)", line) + } + return p.Ref + } + return newError("Mstari %d: huwezi kufikia thamani ya kitu ambacho si pointer", line) + case "&": + if right == nil { + return newError("Mstari %d: huwezi kupata anwani ya kitu kisicho na thamani (nil)", line) + } + return &object.Pointer{Ref: right} default: return newError("Mstari %d: Operesheni Haieleweki: %s%s", line, operator, right.Type()) } diff --git a/examples/pointer.nr b/examples/pointer.nr new file mode 100644 index 0000000..85f942f --- /dev/null +++ b/examples/pointer.nr @@ -0,0 +1,5 @@ +fanya x = 42 * 2 +fanya p = &x +andika(p) +andika("POINTER is",p) +andika("VALUE is",*p) \ No newline at end of file diff --git a/lexer/lexer.go b/lexer/lexer.go index 7d83728..7442517 100644 --- a/lexer/lexer.go +++ b/lexer/lexer.go @@ -153,6 +153,8 @@ func (l *Lexer) NextToken() token.Token { ch := l.ch l.readChar() tok = token.Token{Type: token.AND, Literal: string(ch) + string(l.ch), Line: l.line} + } else { + tok = newToken(token.AMPERSAND, l.line, l.ch) } case rune('|'): if l.peekChar() == rune('|') { diff --git a/object/object.go b/object/object.go index 46de338..abd5289 100644 --- a/object/object.go +++ b/object/object.go @@ -27,6 +27,7 @@ const ( BYTE_OBJ = "BYTE" PACKAGE_OBJ = "PAKEJI" INSTANCE = "PAKEJI" + POINTER_OBJ = "POINTER" AT = "@" ) diff --git a/object/pointer.go b/object/pointer.go new file mode 100644 index 0000000..263375f --- /dev/null +++ b/object/pointer.go @@ -0,0 +1,20 @@ +package object + +import ( + "fmt" +) + +type Pointer struct { + Ref Object +} + +func (p *Pointer) Type() ObjectType { + return POINTER_OBJ +} + +func (p *Pointer) Inspect() string { + if p.Ref == nil { + return "Pointer(anwani=nil, thamani=nil)" + } + return fmt.Sprintf("Pointer(anwani=%p, thamani=%s)", p.Ref, p.Ref.Inspect()) +} diff --git a/parser/parser.go b/parser/parser.go index 0bcf5f8..f65a023 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -113,6 +113,8 @@ func New(l *lexer.Lexer) *Parser { p.registerPrefix(token.IMPORT, p.parseImport) p.registerPrefix(token.PACKAGE, p.parsePackage) p.registerPrefix(token.AT, p.parseAt) + p.registerPrefix(token.AMPERSAND, p.parsePrefixExpression) + p.registerPrefix(token.ASTERISK, p.parsePrefixExpression) p.infixParseFns = make(map[token.TokenType]infixParseFn) p.registerInfix(token.AND, p.parseInfixExpression) diff --git a/token/token.go b/token/token.go index 18c4f6a..5d3f130 100644 --- a/token/token.go +++ b/token/token.go @@ -26,6 +26,7 @@ const ( MINUS = "-" BANG = "!" ASTERISK = "*" + AMPERSAND = "&" POW = "**" SLASH = "/" MODULUS = "%"