-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add trait token * add trait AST * parse traits * evaluate traits * add use token * working traits ✨ * evaluate properties from traits
- Loading branch information
Showing
19 changed files
with
283 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package ast | ||
|
||
import "ghostlang.org/x/ghost/token" | ||
|
||
type Trait struct { | ||
ExpressionNode | ||
Token token.Token | ||
Name *Identifier | ||
Body *Block | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package ast | ||
|
||
import "ghostlang.org/x/ghost/token" | ||
|
||
type Use struct { | ||
ExpressionNode | ||
Token token.Token | ||
Traits []*Identifier | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package evaluator | ||
|
||
import ( | ||
"ghostlang.org/x/ghost/ast" | ||
"ghostlang.org/x/ghost/object" | ||
) | ||
|
||
func evaluateTrait(node *ast.Trait, scope *object.Scope) object.Object { | ||
trait := &object.Trait{ | ||
Name: node.Name, | ||
Scope: scope, | ||
Environment: object.NewEnvironment(), | ||
} | ||
|
||
// Create a new scope for this trait | ||
trait.Environment = object.NewEnclosedEnvironment(scope.Environment) | ||
traitScope := &object.Scope{Environment: trait.Environment, Self: trait} | ||
|
||
result := Evaluate(node.Body, traitScope) | ||
|
||
if isError(result) { | ||
return result | ||
} | ||
|
||
scope.Environment.Set(node.Name.Value, trait) | ||
|
||
return trait | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package evaluator | ||
|
||
import ( | ||
"ghostlang.org/x/ghost/ast" | ||
"ghostlang.org/x/ghost/object" | ||
) | ||
|
||
func evaluateUse(node *ast.Use, scope *object.Scope) object.Object { | ||
// check that the scope is a class | ||
class, ok := scope.Self.(*object.Class) | ||
|
||
if !ok { | ||
return object.NewError("%d:%d:%s: runtime error: use statement can only be used in a class", node.Token.Line, node.Token.Column, node.Token.File) | ||
} | ||
|
||
var traits []*object.Trait | ||
|
||
for _, trait := range node.Traits { | ||
if !scope.Environment.Has(trait.Value) { | ||
return object.NewError("%d:%d:%s: runtime error: trait '%s' is not defined", trait.Token.Line, trait.Token.Column, trait.Token.File, trait.Value) | ||
} | ||
|
||
identifier, _ := scope.Environment.Get(trait.Value) | ||
|
||
t, ok := identifier.(*object.Trait) | ||
|
||
if !ok { | ||
return object.NewError("%d:%d:%s: runtime error: referenced identifier in use not a trait, got=%T", trait.Token.Line, trait.Token.Column, trait.Token.File, trait) | ||
} | ||
|
||
traits = append(traits, t) | ||
} | ||
|
||
class.Traits = traits | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
trait Foo { | ||
message = 'Hello World!!!!' | ||
|
||
function bar() { | ||
console.log(this.message) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,16 @@ | ||
x = 0 | ||
list = [0, 1, 2, 3] | ||
import Foo from 'foo' | ||
|
||
for (i = 0; i < list.length(); i++) { | ||
print(i) | ||
} | ||
class Lorem { | ||
use Foo | ||
|
||
function hello() { | ||
console.log('hello') | ||
} | ||
} | ||
|
||
lorem = Lorem.new() | ||
|
||
lorem.hello() | ||
lorem.bar() | ||
|
||
console.log('done.') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package object | ||
|
||
import "ghostlang.org/x/ghost/ast" | ||
|
||
const TRAIT = "TRAIT" | ||
|
||
// Trait objects consist of a body and an environment. | ||
type Trait struct { | ||
Name *ast.Identifier | ||
Scope *Scope | ||
Environment *Environment | ||
} | ||
|
||
// String represents the class object's value as a string. | ||
func (trait *Trait) String() string { | ||
return "trait" | ||
} | ||
|
||
// Type returns the trait object type. | ||
func (trait *Trait) Type() Type { | ||
return TRAIT | ||
} | ||
|
||
// Method defines the set of methods available on trait objects. | ||
func (trait *Trait) Method(method string, args []Object) (Object, bool) { | ||
return nil, false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package parser | ||
|
||
import ( | ||
"ghostlang.org/x/ghost/ast" | ||
"ghostlang.org/x/ghost/token" | ||
) | ||
|
||
func (parser *Parser) traitStatement() ast.ExpressionNode { | ||
trait := &ast.Trait{Token: parser.currentToken} | ||
|
||
parser.readToken() | ||
|
||
trait.Name = &ast.Identifier{Token: parser.currentToken, Value: parser.currentToken.Lexeme} | ||
|
||
if !parser.expectNextTokenIs(token.LEFTBRACE) { | ||
return nil | ||
} | ||
|
||
trait.Body = parser.blockStatement() | ||
|
||
return trait | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package parser | ||
|
||
import ( | ||
"ghostlang.org/x/ghost/ast" | ||
"ghostlang.org/x/ghost/token" | ||
) | ||
|
||
func (parser *Parser) useExpression() ast.ExpressionNode { | ||
use := &ast.Use{Token: parser.currentToken} | ||
|
||
if !parser.expectNextTokenIs(token.IDENTIFIER) { | ||
return nil | ||
} | ||
|
||
identifier := &ast.Identifier{Token: parser.currentToken, Value: parser.currentToken.Lexeme} | ||
|
||
use.Traits = append(use.Traits, identifier) | ||
|
||
return use | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.