mirror of
				https://github.com/GayPizzaSpecifications/pork.git
				synced 2025-11-03 17:39:38 +00:00 
			
		
		
		
	language: implement let definitions
This commit is contained in:
		@ -137,6 +137,15 @@ types:
 | 
				
			|||||||
      type: Block?
 | 
					      type: Block?
 | 
				
			||||||
    - name: native
 | 
					    - name: native
 | 
				
			||||||
      type: Native?
 | 
					      type: Native?
 | 
				
			||||||
 | 
					  LetDefinition:
 | 
				
			||||||
 | 
					    parent: Definition
 | 
				
			||||||
 | 
					    values:
 | 
				
			||||||
 | 
					    - name: modifiers
 | 
				
			||||||
 | 
					      type: DefinitionModifiers
 | 
				
			||||||
 | 
					    - name: symbol
 | 
				
			||||||
 | 
					      type: Symbol
 | 
				
			||||||
 | 
					    - name: value
 | 
				
			||||||
 | 
					      type: Expression
 | 
				
			||||||
  If:
 | 
					  If:
 | 
				
			||||||
    parent: Expression
 | 
					    parent: Expression
 | 
				
			||||||
    values:
 | 
					    values:
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,7 @@ digraph A {
 | 
				
			|||||||
  type_FunctionCall [shape=box,label="FunctionCall"]
 | 
					  type_FunctionCall [shape=box,label="FunctionCall"]
 | 
				
			||||||
  type_ArgumentSpec [shape=box,label="ArgumentSpec"]
 | 
					  type_ArgumentSpec [shape=box,label="ArgumentSpec"]
 | 
				
			||||||
  type_FunctionDefinition [shape=box,label="FunctionDefinition"]
 | 
					  type_FunctionDefinition [shape=box,label="FunctionDefinition"]
 | 
				
			||||||
 | 
					  type_LetDefinition [shape=box,label="LetDefinition"]
 | 
				
			||||||
  type_If [shape=box,label="If"]
 | 
					  type_If [shape=box,label="If"]
 | 
				
			||||||
  type_ImportDeclaration [shape=box,label="ImportDeclaration"]
 | 
					  type_ImportDeclaration [shape=box,label="ImportDeclaration"]
 | 
				
			||||||
  type_IntegerLiteral [shape=box,label="IntegerLiteral"]
 | 
					  type_IntegerLiteral [shape=box,label="IntegerLiteral"]
 | 
				
			||||||
@ -58,6 +59,7 @@ digraph A {
 | 
				
			|||||||
  type_Expression -> type_Break
 | 
					  type_Expression -> type_Break
 | 
				
			||||||
  type_Expression -> type_Continue
 | 
					  type_Expression -> type_Continue
 | 
				
			||||||
  type_Definition -> type_FunctionDefinition
 | 
					  type_Definition -> type_FunctionDefinition
 | 
				
			||||||
 | 
					  type_Definition -> type_LetDefinition
 | 
				
			||||||
  type_Declaration -> type_ImportDeclaration
 | 
					  type_Declaration -> type_ImportDeclaration
 | 
				
			||||||
  type_Definition -> type_Symbol [style=dotted]
 | 
					  type_Definition -> type_Symbol [style=dotted]
 | 
				
			||||||
  type_Definition -> type_DefinitionModifiers [style=dotted]
 | 
					  type_Definition -> type_DefinitionModifiers [style=dotted]
 | 
				
			||||||
@ -80,6 +82,9 @@ digraph A {
 | 
				
			|||||||
  type_FunctionDefinition -> type_ArgumentSpec [style=dotted]
 | 
					  type_FunctionDefinition -> type_ArgumentSpec [style=dotted]
 | 
				
			||||||
  type_FunctionDefinition -> type_Block [style=dotted]
 | 
					  type_FunctionDefinition -> type_Block [style=dotted]
 | 
				
			||||||
  type_FunctionDefinition -> type_Native [style=dotted]
 | 
					  type_FunctionDefinition -> type_Native [style=dotted]
 | 
				
			||||||
 | 
					  type_LetDefinition -> type_DefinitionModifiers [style=dotted]
 | 
				
			||||||
 | 
					  type_LetDefinition -> type_Symbol [style=dotted]
 | 
				
			||||||
 | 
					  type_LetDefinition -> type_Expression [style=dotted]
 | 
				
			||||||
  type_If -> type_Expression [style=dotted]
 | 
					  type_If -> type_Expression [style=dotted]
 | 
				
			||||||
  type_If -> type_Block [style=dotted]
 | 
					  type_If -> type_Block [style=dotted]
 | 
				
			||||||
  type_ImportDeclaration -> type_Symbol [style=dotted]
 | 
					  type_ImportDeclaration -> type_Symbol [style=dotted]
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										30
									
								
								ast/src/main/kotlin/gay/pizza/pork/ast/LetDefinition.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								ast/src/main/kotlin/gay/pizza/pork/ast/LetDefinition.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					// GENERATED CODE FROM PORK AST CODEGEN
 | 
				
			||||||
 | 
					package gay.pizza.pork.ast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import kotlinx.serialization.SerialName
 | 
				
			||||||
 | 
					import kotlinx.serialization.Serializable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Serializable
 | 
				
			||||||
 | 
					@SerialName("letDefinition")
 | 
				
			||||||
 | 
					class LetDefinition(override val modifiers: DefinitionModifiers, override val symbol: Symbol, val value: Expression) : Definition() {
 | 
				
			||||||
 | 
					  override val type: NodeType = NodeType.LetDefinition
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> =
 | 
				
			||||||
 | 
					    visitor.visitNodes(symbol, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun <T> visit(visitor: NodeVisitor<T>): T =
 | 
				
			||||||
 | 
					    visitor.visitLetDefinition(this)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun equals(other: Any?): Boolean {
 | 
				
			||||||
 | 
					    if (other !is LetDefinition) return false
 | 
				
			||||||
 | 
					    return other.modifiers == modifiers && other.symbol == symbol && other.value == value
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun hashCode(): Int {
 | 
				
			||||||
 | 
					    var result = modifiers.hashCode()
 | 
				
			||||||
 | 
					    result = 31 * result + symbol.hashCode()
 | 
				
			||||||
 | 
					    result = 31 * result + value.hashCode()
 | 
				
			||||||
 | 
					    result = 31 * result + type.hashCode()
 | 
				
			||||||
 | 
					    return result
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -41,6 +41,9 @@ class NodeCoalescer(val handler: (Node) -> Unit) : NodeVisitor<Unit> {
 | 
				
			|||||||
  override fun visitLetAssignment(node: LetAssignment): Unit =
 | 
					  override fun visitLetAssignment(node: LetAssignment): Unit =
 | 
				
			||||||
    handle(node)
 | 
					    handle(node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun visitLetDefinition(node: LetDefinition): Unit =
 | 
				
			||||||
 | 
					    handle(node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun visitListLiteral(node: ListLiteral): Unit =
 | 
					  override fun visitListLiteral(node: ListLiteral): Unit =
 | 
				
			||||||
    handle(node)
 | 
					    handle(node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,7 @@ enum class NodeType(val parent: NodeType? = null) {
 | 
				
			|||||||
  InfixOperation(Expression),
 | 
					  InfixOperation(Expression),
 | 
				
			||||||
  IntegerLiteral(Expression),
 | 
					  IntegerLiteral(Expression),
 | 
				
			||||||
  LetAssignment(Expression),
 | 
					  LetAssignment(Expression),
 | 
				
			||||||
 | 
					  LetDefinition(Definition),
 | 
				
			||||||
  ListLiteral(Expression),
 | 
					  ListLiteral(Expression),
 | 
				
			||||||
  Native(Node),
 | 
					  Native(Node),
 | 
				
			||||||
  Parentheses(Expression),
 | 
					  Parentheses(Expression),
 | 
				
			||||||
 | 
				
			|||||||
@ -28,6 +28,8 @@ interface NodeVisitor<T> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  fun visitLetAssignment(node: LetAssignment): T
 | 
					  fun visitLetAssignment(node: LetAssignment): T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fun visitLetDefinition(node: LetDefinition): T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fun visitListLiteral(node: ListLiteral): T
 | 
					  fun visitListLiteral(node: ListLiteral): T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fun visitNative(node: Native): T
 | 
					  fun visitNative(node: Native): T
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@ fun <T> NodeVisitor<T>.visit(node: Node): T =
 | 
				
			|||||||
    is BooleanLiteral -> visitBooleanLiteral(node)
 | 
					    is BooleanLiteral -> visitBooleanLiteral(node)
 | 
				
			||||||
    is FunctionCall -> visitFunctionCall(node)
 | 
					    is FunctionCall -> visitFunctionCall(node)
 | 
				
			||||||
    is FunctionDefinition -> visitFunctionDefinition(node)
 | 
					    is FunctionDefinition -> visitFunctionDefinition(node)
 | 
				
			||||||
 | 
					    is LetDefinition -> visitLetDefinition(node)
 | 
				
			||||||
    is If -> visitIf(node)
 | 
					    is If -> visitIf(node)
 | 
				
			||||||
    is ImportDeclaration -> visitImportDeclaration(node)
 | 
					    is ImportDeclaration -> visitImportDeclaration(node)
 | 
				
			||||||
    is IntegerLiteral -> visitIntegerLiteral(node)
 | 
					    is IntegerLiteral -> visitIntegerLiteral(node)
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,10 @@ class CompilationUnitContext(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  private fun definitionValue(definition: Definition): Any = when (definition) {
 | 
					  private fun definitionValue(definition: Definition): Any = when (definition) {
 | 
				
			||||||
    is FunctionDefinition -> FunctionContext(this, definition)
 | 
					    is FunctionDefinition -> FunctionContext(this, definition)
 | 
				
			||||||
 | 
					    is LetDefinition -> {
 | 
				
			||||||
 | 
					      EvaluationVisitor(internalScope.fork("let ${definition.symbol.id}"))
 | 
				
			||||||
 | 
					        .visit(definition.value)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private fun processAllImports() {
 | 
					  private fun processAllImports() {
 | 
				
			||||||
 | 
				
			|||||||
@ -30,6 +30,10 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
 | 
				
			|||||||
    return value
 | 
					    return value
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun visitLetDefinition(node: LetDefinition): Any {
 | 
				
			||||||
 | 
					    topLevelUsedError("LetDefinition", "CompilationUnitContext")
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun visitSymbolReference(node: SymbolReference): Any =
 | 
					  override fun visitSymbolReference(node: SymbolReference): Any =
 | 
				
			||||||
    currentScope.value(node.symbol.id)
 | 
					    currentScope.value(node.symbol.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,9 @@
 | 
				
			|||||||
 | 
					let count = 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export func main() {
 | 
					export func main() {
 | 
				
			||||||
  var x = 1
 | 
					  var x = 1
 | 
				
			||||||
  while x <= 5 {
 | 
					  while x <= count {
 | 
				
			||||||
    println(x)
 | 
					    println(x)
 | 
				
			||||||
    x = x + 1
 | 
					    x++
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -226,7 +226,7 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
 | 
				
			|||||||
    ImportDeclaration(form, components)
 | 
					    ImportDeclaration(form, components)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private fun readFunctionDeclaration(): FunctionDefinition = within {
 | 
					  private fun readDefinitionModifiers(): DefinitionModifiers {
 | 
				
			||||||
    val modifiers = DefinitionModifiers(export = false)
 | 
					    val modifiers = DefinitionModifiers(export = false)
 | 
				
			||||||
    while (true) {
 | 
					    while (true) {
 | 
				
			||||||
      val token = peek()
 | 
					      val token = peek()
 | 
				
			||||||
@ -238,12 +238,16 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
 | 
				
			|||||||
        else -> break
 | 
					        else -> break
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return modifiers
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private fun readFunctionDeclaration(modifiers: DefinitionModifiers): FunctionDefinition = within {
 | 
				
			||||||
    expect(TokenType.Func)
 | 
					    expect(TokenType.Func)
 | 
				
			||||||
    val name = readSymbolRaw()
 | 
					    val name = readSymbolRaw()
 | 
				
			||||||
    expect(TokenType.LeftParentheses)
 | 
					    expect(TokenType.LeftParentheses)
 | 
				
			||||||
    val arguments = collect(TokenType.RightParentheses, TokenType.Comma) {
 | 
					    val arguments = collect(TokenType.RightParentheses, TokenType.Comma) {
 | 
				
			||||||
      val symbol = readSymbolRaw()
 | 
					      val symbol = readSymbolRaw()
 | 
				
			||||||
      var multiple: Boolean = false
 | 
					      var multiple = false
 | 
				
			||||||
      if (next(TokenType.DotDotDot)) {
 | 
					      if (next(TokenType.DotDotDot)) {
 | 
				
			||||||
        multiple = true
 | 
					        multiple = true
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@ -261,11 +265,21 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
 | 
				
			|||||||
    FunctionDefinition(modifiers, name, arguments, block, native)
 | 
					    FunctionDefinition(modifiers, name, arguments, block, native)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private fun readLetDefinition(modifiers: DefinitionModifiers): LetDefinition = within {
 | 
				
			||||||
 | 
					    val modifiers = readDefinitionModifiers()
 | 
				
			||||||
 | 
					    expect(TokenType.Let)
 | 
				
			||||||
 | 
					    val name = readSymbolRaw()
 | 
				
			||||||
 | 
					    expect(TokenType.Equals)
 | 
				
			||||||
 | 
					    val value = readExpression()
 | 
				
			||||||
 | 
					    LetDefinition(modifiers, name, value)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private fun maybeReadDefinition(): Definition? {
 | 
					  private fun maybeReadDefinition(): Definition? {
 | 
				
			||||||
 | 
					    val modifiers = readDefinitionModifiers()
 | 
				
			||||||
    val token = peek()
 | 
					    val token = peek()
 | 
				
			||||||
    return when (token.type) {
 | 
					    return when (token.type) {
 | 
				
			||||||
      TokenType.Export,
 | 
					      TokenType.Func -> readFunctionDeclaration(modifiers)
 | 
				
			||||||
      TokenType.Func -> readFunctionDeclaration()
 | 
					      TokenType.Let -> readLetDefinition(modifiers)
 | 
				
			||||||
      else -> null
 | 
					      else -> null
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -91,6 +91,14 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
 | 
				
			|||||||
    visit(node.value)
 | 
					    visit(node.value)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun visitLetDefinition(node: LetDefinition) {
 | 
				
			||||||
 | 
					    visitDefinitionModifiers(node.modifiers)
 | 
				
			||||||
 | 
					    append("let ")
 | 
				
			||||||
 | 
					    visit(node.symbol)
 | 
				
			||||||
 | 
					    append(" = ")
 | 
				
			||||||
 | 
					    visit(node.value)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun visitSymbolReference(node: SymbolReference) {
 | 
					  override fun visitSymbolReference(node: SymbolReference) {
 | 
				
			||||||
    visit(node.symbol)
 | 
					    visit(node.symbol)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -152,10 +160,14 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
 | 
				
			|||||||
    visit(node.right)
 | 
					    visit(node.right)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun visitFunctionDefinition(node: FunctionDefinition) {
 | 
					  private fun visitDefinitionModifiers(modifiers: DefinitionModifiers) {
 | 
				
			||||||
    if (node.modifiers.export) {
 | 
					    if (modifiers.export) {
 | 
				
			||||||
      append("export ")
 | 
					      append("export ")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun visitFunctionDefinition(node: FunctionDefinition) {
 | 
				
			||||||
 | 
					    visitDefinitionModifiers(node.modifiers)
 | 
				
			||||||
    append("func ")
 | 
					    append("func ")
 | 
				
			||||||
    visit(node.symbol)
 | 
					    visit(node.symbol)
 | 
				
			||||||
    append("(")
 | 
					    append("(")
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user