VARIABLESSSS
This commit is contained in:
		
							
								
								
									
										32
									
								
								AST.py
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								AST.py
									
									
									
									
									
								
							| @@ -7,6 +7,7 @@ class NodeType(Enum): | ||||
|  | ||||
|     # Statements | ||||
|     ExpressionStatement = "ExpressionStatement" | ||||
|     AssignmentStatement = "AssignmentStatement" | ||||
|  | ||||
|     # Expressions | ||||
|     InfixExpression = "InfixExpression" | ||||
| @@ -14,6 +15,7 @@ class NodeType(Enum): | ||||
|     # Literals | ||||
|     IntegerLiteral = "IntegerLiteral" | ||||
|     FloatLiteral = "FloatLiteral" | ||||
|     IdentifierLiteral = "IdentifierLiteral" | ||||
|  | ||||
| class Node: | ||||
|     @abstractmethod | ||||
| @@ -56,6 +58,23 @@ class ExpressionStatement(Statement): | ||||
|             "type": self.type().value, | ||||
|             "expr": self.expr.json() | ||||
|         } | ||||
|      | ||||
| class AssignmentStatement(Statement): | ||||
|     def __init__(self, name: Expression = None, value: Expression = None, value_type: str = None) -> None: | ||||
|         self.name = name | ||||
|         self.value = value | ||||
|         self.value_type = value_type | ||||
|  | ||||
|     def type(self) -> NodeType: | ||||
|         return NodeType.AssignmentStatement | ||||
|      | ||||
|     def json(self) -> dict: | ||||
|         return { | ||||
|             "type": self.type().value, | ||||
|             "name": self.name.json(), | ||||
|             "value": self.value.json(), | ||||
|             "value_type": self.value_type | ||||
|         } | ||||
| # endregion | ||||
|  | ||||
| # region Expressions | ||||
| @@ -103,4 +122,17 @@ class FloatLiteral(Expression): | ||||
|             "type": self.type().value, | ||||
|             "value": self.value | ||||
|         } | ||||
|      | ||||
| class IdentifierLiteral(Expression): | ||||
|     def __init__(self, value: str = None) -> None: | ||||
|         self.value: str = value | ||||
|  | ||||
|     def type(self) -> NodeType: | ||||
|         return NodeType.IdentifierLiteral | ||||
|      | ||||
|     def json(self) -> dict: | ||||
|         return { | ||||
|             "type": self.type().value, | ||||
|             "value": self.value | ||||
|         } | ||||
| # endregion | ||||
							
								
								
									
										152
									
								
								compiler.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								compiler.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,152 @@ | ||||
| from llvmlite import ir | ||||
|  | ||||
| from AST import Node, NodeType, Program, Expression | ||||
| from AST import ExpressionStatement, AssignmentStatement | ||||
| from AST import InfixExpression | ||||
| from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral | ||||
|  | ||||
| from environment import Environment | ||||
|  | ||||
|  | ||||
| class Compiler: | ||||
| 	def __init__(self) -> None: | ||||
| 		self.type_map: dict[str, ir.type] = { | ||||
| 			"bool": ir.IntType(1), | ||||
| 			"byte": ir.IntType(8), | ||||
| 			"short": ir.IntType(16), | ||||
| 			"int": ir.IntType(32), | ||||
| 			"long": ir.IntType(64), | ||||
| 			"float": ir.FloatType(), | ||||
| 			"double": ir.DoubleType() | ||||
| 		} | ||||
|  | ||||
| 		self.module: ir.Module = ir.Module("main") | ||||
| 		self.builder: ir.IRBuilder = ir.IRBuilder() | ||||
| 		self.environment: Environment = Environment() | ||||
|  | ||||
| 	def compile(self, node: Node) -> None: | ||||
| 		match node.type(): | ||||
| 			case NodeType.Program: | ||||
| 				self.__visit_program(node) | ||||
|  | ||||
| 			# Statements | ||||
| 			case NodeType.ExpressionStatement: | ||||
| 				self.__visit_expression_statement(node) | ||||
| 			case NodeType.AssignmentStatement: | ||||
| 				self.__visit_assignment_statement(node) | ||||
|  | ||||
| 			# Expressions | ||||
| 			case NodeType.InfixExpression: | ||||
| 				self.__visit_infix_expression(node) | ||||
|  | ||||
| 	# region Visit Methods | ||||
| 	def __visit_program(self, node: Program) -> None: | ||||
| 		func_main: str = "main" | ||||
| 		param_types: list[ir.Type] = [] | ||||
| 		return_type = ir.Type = self.type_map["int"] | ||||
|  | ||||
| 		fnty = ir.FunctionType(return_type, param_types) | ||||
| 		func = ir.Function(self.module, fnty, func_main) | ||||
|  | ||||
| 		block = func.append_basic_block(f"{func_main}_entry") | ||||
|  | ||||
| 		self.builder = ir.IRBuilder(block) | ||||
|  | ||||
| 		for stmt in node.statements: | ||||
| 			self.compile(stmt) | ||||
|  | ||||
| 		return_value: ir.Constant = ir.Constant(self.type_map["int"], 123) | ||||
| 		self.builder.ret(return_value) | ||||
|  | ||||
| 	# region Statements | ||||
| 	def __visit_expression_statement(self, node: ExpressionStatement) -> None: | ||||
| 		self.compile(node.expr) | ||||
|  | ||||
| 	def __visit_assignment_statement(self, node: AssignmentStatement) -> None: | ||||
| 		name: str = node.name.value | ||||
| 		value: Expression = node.value | ||||
| 		value_type: str = node.value_type # TODO: implemented | ||||
|  | ||||
| 		value, Type = self.__resolve_value(node=value) | ||||
|  | ||||
| 		if self.environment.lookup(name) is None: | ||||
| 			# Define and allocate the new variable | ||||
| 			ptr = self.builder.alloca(Type) | ||||
|  | ||||
| 			# Storing the value to the ptr | ||||
| 			self.builder.store(value, ptr) | ||||
|  | ||||
| 			# Add the variable to the environment | ||||
| 			self.environment.define(name, value, Type) | ||||
| 		else: | ||||
| 			ptr, _ = self.environment.lookup(name) | ||||
| 			self.builder.store(value, ptr) | ||||
| 	# endregion | ||||
|  | ||||
| 	# region Expressions | ||||
| 	def __visit_infix_expression(self, node: InfixExpression) -> None: | ||||
| 		operator: str = node.operator | ||||
|  | ||||
| 		left_value, left_type = self.__resolve_value(node.left_node) | ||||
| 		right_value, right_type = self.__resolve_value(node.right_node) | ||||
|  | ||||
| 		value = None | ||||
| 		Type = None | ||||
| 		if isinstance(right_type, ir.IntType) and isinstance(left_type, ir.IntType): | ||||
| 			Type = self.type_map["int"] | ||||
| 			match operator: | ||||
| 				case "+": | ||||
| 					value = self.builder.add(left_value, right_value) | ||||
| 				case "-": | ||||
| 					value = self.builder.sub(left_value, right_value) | ||||
| 				case "*": | ||||
| 					value = self.builder.mul(left_value, right_value) | ||||
| 				case "/": | ||||
| 					value = self.builder.sdiv(left_value, right_value) | ||||
| 				case "%": | ||||
| 					value = self.builder.srem(left_value, right_value) | ||||
| 				case "^": | ||||
| 					# TODO | ||||
| 					pass | ||||
| 		elif isinstance(right_type, ir.FloatType) and isinstance(left_type, ir.FloatType): | ||||
| 			Type = self.type_map["float"] | ||||
| 			match operator: | ||||
| 				case "+": | ||||
| 					value = self.builder.fadd(left_value, right_value) | ||||
| 				case "-": | ||||
| 					value = self.builder.fsub(left_value, right_value) | ||||
| 				case "*": | ||||
| 					value = self.builder.fmul(left_value, right_value) | ||||
| 				case "/": | ||||
| 					value = self.builder.fdiv(left_value, right_value) | ||||
| 				case "%": | ||||
| 					value = self.builder.frem(left_value, right_value) | ||||
| 				case "^": | ||||
| 					# TODO | ||||
| 					pass | ||||
| 		 | ||||
| 		return value, Type | ||||
| 	# endregion | ||||
|  | ||||
| 	# endregion | ||||
|  | ||||
| 	# region Helper Methods | ||||
| 	def __resolve_value(self, node: Expression) -> tuple[ir.Value, ir.Type]: | ||||
| 		match node.type(): | ||||
| 			case NodeType.IntegerLiteral: | ||||
| 				node: IntegerLiteral = node | ||||
| 				value, Type = node.value, self.type_map['int'] | ||||
| 				return ir.Constant(Type, value), Type | ||||
| 			case NodeType.FloatLiteral: | ||||
| 				node: FloatLiteral = node | ||||
| 				value, Type = node.value, self.type_map['float'] | ||||
| 				return ir.Constant(Type, value), Type | ||||
| 			case NodeType.IdentifierLiteral: | ||||
| 				node: IdentifierLiteral = node | ||||
| 				ptr, Type = self.environment.lookup(node.value) | ||||
| 				return self.builder.load(ptr), Type | ||||
|  | ||||
| 			# expression value | ||||
| 			case NodeType.InfixExpression: | ||||
| 				return self.__visit_infix_expression(node) | ||||
| 	# endregion | ||||
| @@ -2,36 +2,17 @@ | ||||
|     "type": "Program", | ||||
|     "statements": [ | ||||
|         { | ||||
|             "ExpressionStatement": { | ||||
|                 "type": "ExpressionStatement", | ||||
|                 "expr": { | ||||
|                     "type": "InfixExpression", | ||||
|                     "left_node": { | ||||
|                         "type": "InfixExpression", | ||||
|                         "left_node": { | ||||
|                             "type": "InfixExpression", | ||||
|                             "left_node": { | ||||
|                                 "type": "IntegerLiteral", | ||||
|                                 "value": 5 | ||||
|                             }, | ||||
|                             "operator": "+", | ||||
|                             "right_node": { | ||||
|                                 "type": "IntegerLiteral", | ||||
|                                 "value": 5 | ||||
|                             } | ||||
|                         }, | ||||
|                         "operator": "*", | ||||
|                         "right_node": { | ||||
|                             "type": "IntegerLiteral", | ||||
|                             "value": 3 | ||||
|                         } | ||||
|                     }, | ||||
|                     "operator": "+", | ||||
|                     "right_node": { | ||||
|                         "type": "IntegerLiteral", | ||||
|                         "value": 2 | ||||
|                     } | ||||
|                 } | ||||
|             "AssignmentStatement": { | ||||
|                 "type": "AssignmentStatement", | ||||
|                 "name": { | ||||
|                     "type": "IdentifierLiteral", | ||||
|                     "value": "myVar" | ||||
|                 }, | ||||
|                 "value": { | ||||
|                     "type": "IntegerLiteral", | ||||
|                     "value": 1 | ||||
|                 }, | ||||
|                 "value_type": "Bool" | ||||
|             } | ||||
|         } | ||||
|     ] | ||||
|   | ||||
							
								
								
									
										13
									
								
								debug/ir.ll
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								debug/ir.ll
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| ; ModuleID = "main" | ||||
| target triple = "x86_64-pc-windows-msvc" | ||||
| target datalayout = "" | ||||
|  | ||||
| define i32 @"main"() | ||||
| { | ||||
| main_entry: | ||||
|   %".2" = alloca float | ||||
|   store float 0x3ff3ae1480000000, float* %".2" | ||||
|   %".4" = alloca i32 | ||||
|   store i32 456, i32* %".4" | ||||
|   ret i32 123 | ||||
| } | ||||
							
								
								
									
										23
									
								
								environment.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								environment.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| from llvmlite import ir | ||||
|  | ||||
|  | ||||
| class Environment: | ||||
| 	def __init__(self, records: dict[str, tuple[ir.Value, ir.Type]] = None, parent = None, name: str = "global") -> None: | ||||
| 		self.records: dict[str, tuple[ir.Value, ir.Type]] = records if records else {} | ||||
| 		self.parent = parent | ||||
| 		self.name: str = name | ||||
|  | ||||
| 	def define(self, name: str, value: ir.Value, _type: ir.Type) -> ir.Value: | ||||
| 		self.records[name] = (value, _type) | ||||
| 		return value | ||||
| 	 | ||||
| 	def lookup(self, name: str) -> tuple[ir.Value, ir.Type]: | ||||
| 		return self.__resolve(name) | ||||
| 	 | ||||
| 	def __resolve(self, name: str) -> tuple[ir.Value, ir.Type]: | ||||
| 		if name in self.records: | ||||
| 			return self.records[name] | ||||
| 		elif self.parent: | ||||
| 			return self.parent.__resolve(name) | ||||
| 		else: | ||||
| 			return None | ||||
							
								
								
									
										20
									
								
								lexer.py
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								lexer.py
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| from lexer_token import Token, TokenType | ||||
| from lexer_token import Token, TokenType, lookup_ident | ||||
| from typing import Any | ||||
|  | ||||
|  | ||||
| @@ -36,6 +36,9 @@ class Lexer: | ||||
| 	def __is_digit(self, char: str) -> bool: | ||||
| 		return "0" <= char and char <= "9" | ||||
| 	 | ||||
| 	def __is_letter(self, char: str) -> bool: | ||||
| 		return "a" <= char and char <= "z" or "A" <= char and char <= "Z" or char == "_" | ||||
| 	 | ||||
| 	def __read_number(self) -> Token: | ||||
| 		start_pos: int = self.position | ||||
| 		dot_count: int = 0 | ||||
| @@ -61,6 +64,13 @@ class Lexer: | ||||
| 		else: | ||||
| 			return self.__new_token(TokenType.FLOAT, float(output)) | ||||
|  | ||||
| 	def __read_identifier(self) -> str: | ||||
| 		position = self.position | ||||
| 		while self.current_char is not None and (self.__is_letter(self.current_char) or self.current_char.isalnum()): | ||||
| 			self.__read_char() | ||||
|  | ||||
| 		return self.source[position:self.position] | ||||
|  | ||||
| 	def next_token(self) -> Token: | ||||
| 		tok: Token = None | ||||
|  | ||||
| @@ -79,6 +89,8 @@ class Lexer: | ||||
| 				tok = self.__new_token(TokenType.POW, self.current_char) | ||||
| 			case "%": | ||||
| 				tok = self.__new_token(TokenType.MODULUS, self.current_char) | ||||
| 			case "=": | ||||
| 				tok = self.__new_token(TokenType.EQ, self.current_char) | ||||
| 			case "(": | ||||
| 				tok = self.__new_token(TokenType.LPAREN, self.current_char) | ||||
| 			case ")": | ||||
| @@ -98,6 +110,12 @@ class Lexer: | ||||
| 			case None: | ||||
| 				tok = self.__new_token(TokenType.EOF, "") | ||||
| 			case _: | ||||
| 				if self.__is_letter(self.current_char): | ||||
| 					literal: str = self.__read_identifier() | ||||
| 					tt: TokenType = lookup_ident(literal) | ||||
| 					tok = self.__new_token(tt, literal) | ||||
| 					return tok | ||||
| 				 | ||||
| 				if self.__is_digit(self.current_char): | ||||
| 					tok = self.__read_number() | ||||
| 					return tok | ||||
|   | ||||
| @@ -8,6 +8,7 @@ class TokenType(Enum): | ||||
| 	ILLEGAL = "ILLEGAL" | ||||
|  | ||||
| 	# Data types | ||||
| 	IDENT = "IDENT" | ||||
| 	INT = "INT" | ||||
| 	FLOAT = "FLOAT" | ||||
|  | ||||
| @@ -19,6 +20,9 @@ class TokenType(Enum): | ||||
| 	POW = "POW" | ||||
| 	MODULUS = "MODULUS" | ||||
|  | ||||
| 	# Assignment symbols | ||||
| 	EQ = "EQ" | ||||
|  | ||||
| 	# Symbols | ||||
| 	LPAREN = "LPAREN" | ||||
| 	RPAREN = "RPAREN" | ||||
| @@ -29,6 +33,11 @@ class TokenType(Enum): | ||||
| 	COLON = "COLON" | ||||
| 	SEMICOLON = "SEMICOLON" | ||||
|  | ||||
| 	# Keywords | ||||
|  | ||||
| 	# Typing | ||||
| 	TYPE = "TYPE" | ||||
|  | ||||
| class Token: | ||||
| 	def __init__(self, type: TokenType, literal: Any, line_no: int, position: int) -> None: | ||||
| 		self.type = type | ||||
| @@ -40,4 +49,29 @@ class Token: | ||||
| 		return f"token[{self.type} : {self.literal} : Line {self.line_no} : Position {self.position}]" | ||||
| 	 | ||||
| 	def __repr__(self) -> str: | ||||
| 		return str(self) | ||||
| 		return str(self) | ||||
| 	 | ||||
|  | ||||
| KEYWORDS: dict[str, TokenType] = { | ||||
| 	 | ||||
| } | ||||
|  | ||||
| ALT_KEYWORDS: dict[str, TokenType] = { | ||||
|  | ||||
| } | ||||
|  | ||||
| TYPE_KEYWORDS: list[str] = ["Int", "Float", "String", "Bool", "List", "Nil"] | ||||
|  | ||||
| def lookup_ident(ident: str) -> TokenType: | ||||
| 	tt: TokenType | None = KEYWORDS.get(ident) | ||||
| 	if tt is not None: | ||||
| 		return tt | ||||
| 	 | ||||
| 	tt: TokenType | None = ALT_KEYWORDS.get(ident) | ||||
| 	if tt is not None: | ||||
| 		return tt | ||||
| 	 | ||||
| 	if ident in TYPE_KEYWORDS: | ||||
| 		return TokenType.TYPE | ||||
| 	 | ||||
| 	return TokenType.IDENT | ||||
							
								
								
									
										32
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								main.py
									
									
									
									
									
								
							| @@ -1,14 +1,20 @@ | ||||
| from lexer import Lexer | ||||
| from plasma_parser import Parser | ||||
| from compiler import Compiler | ||||
| from AST import Program | ||||
| import json | ||||
|  | ||||
| LEXER_DEBUG: bool = True | ||||
| PARSER_DEBUG: bool = True | ||||
| from llvmlite import ir | ||||
| from llvmlite.binding import targets | ||||
| from ctypes import CFUNCTYPE, c_int, c_float | ||||
|  | ||||
| LEXER_DEBUG: bool = False | ||||
| PARSER_DEBUG: bool = False | ||||
| COMPILER_DEBUG: bool = True | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
| 	with open("tests/parser.pla") as f: | ||||
| 	with open("tests/test.pla") as f: | ||||
| 		code: str = f.read() | ||||
|  | ||||
| 	if LEXER_DEBUG: | ||||
| @@ -19,11 +25,27 @@ if __name__ == "__main__": | ||||
| 	l: Lexer = Lexer(source=code) | ||||
| 	p: Parser = Parser(lexer=l) | ||||
|  | ||||
| 	program: Program = p.parse_program() | ||||
| 	if len(p.errors) > 0: | ||||
| 		for err in p.errors: | ||||
| 			print(err) | ||||
| 		exit(1) | ||||
|  | ||||
| 	if PARSER_DEBUG: | ||||
| 		print("===== PARSER DEBUG =====") | ||||
| 		program: Program = p.parse_program() | ||||
| 		#program: Program = p.parse_program() | ||||
|  | ||||
| 		with open("debug/ast.json", "w") as f: | ||||
| 			json.dump(program.json(), f, indent=4) | ||||
|  | ||||
| 		print("Wrote AST to debug/ast.json successfully.") | ||||
| 		print("Wrote AST to debug/ast.json successfully.") | ||||
|  | ||||
| 	c: Compiler = Compiler() | ||||
| 	c.compile(program) | ||||
|  | ||||
| 	module: ir.Module = c.module | ||||
| 	module.triple = targets.get_default_triple() | ||||
|  | ||||
| 	if COMPILER_DEBUG: | ||||
| 		with open("debug/ir.ll", "w") as f: | ||||
| 			f.write(str(module)) | ||||
| @@ -4,9 +4,9 @@ from typing import Callable | ||||
| from enum import Enum, auto | ||||
|  | ||||
| from AST import Statement, Expression, Program | ||||
| from AST import ExpressionStatement | ||||
| from AST import ExpressionStatement, AssignmentStatement | ||||
| from AST import InfixExpression | ||||
| from AST import IntegerLiteral, FloatLiteral | ||||
| from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral | ||||
|  | ||||
| class PrecedenceType(Enum): | ||||
| 	P_LOWEST = 0 | ||||
| @@ -63,6 +63,9 @@ class Parser: | ||||
| 		self.current_token = self.peek_token | ||||
| 		self.peek_token = self.lexer.next_token() | ||||
|  | ||||
| 	def __current_token_is(self, tt: TokenType) -> bool: | ||||
| 		return self.current_token.type == tt | ||||
|  | ||||
| 	def __peek_token_is(self, tt: TokenType) -> bool: | ||||
| 		return self.peek_token.type == tt | ||||
| 	 | ||||
| @@ -108,7 +111,11 @@ class Parser: | ||||
| 	 | ||||
| 	# region Statement Methods | ||||
| 	def __parse_statement(self) -> Statement: | ||||
| 		return self.__parse_expression_statement() | ||||
| 		match self.current_token.type: | ||||
| 			case TokenType.IDENT: | ||||
| 				return self.__parse_assignment_statement() | ||||
| 			case _: | ||||
| 				return self.__parse_expression_statement() | ||||
| 	 | ||||
| 	def __parse_expression_statement(self) -> ExpressionStatement: | ||||
| 		expr = self.__parse_expression(PrecedenceType.P_LOWEST) | ||||
| @@ -119,6 +126,30 @@ class Parser: | ||||
| 		stmt: ExpressionStatement = ExpressionStatement(expr=expr) | ||||
|  | ||||
| 		return stmt | ||||
| 	 | ||||
| 	def __parse_assignment_statement(self) -> AssignmentStatement: | ||||
| 		# x: Int = 10; | ||||
| 		stmt: AssignmentStatement = AssignmentStatement(name=IdentifierLiteral(self.current_token.literal)) | ||||
|  | ||||
| 		if not self.__expect_peek(TokenType.COLON): | ||||
| 			return None | ||||
| 		 | ||||
| 		if not self.__expect_peek(TokenType.TYPE): | ||||
| 			return None | ||||
| 		 | ||||
| 		stmt.value_type = self.current_token.literal | ||||
| 		 | ||||
| 		if not self.__expect_peek(TokenType.EQ): | ||||
| 			return None | ||||
| 		 | ||||
| 		self.__next_token() | ||||
|  | ||||
| 		stmt.value = self.__parse_expression(PrecedenceType.P_LOWEST) | ||||
|  | ||||
| 		while not self.__current_token_is(TokenType.SEMICOLON) and not self.__current_token_is(TokenType.EOF): | ||||
| 			self.__next_token() | ||||
|  | ||||
| 		return stmt | ||||
| 	# endregion | ||||
|  | ||||
| 	# region Expression Methods | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| depend "io.pla" | ||||
|  | ||||
| if (1 + 2 == 3) { | ||||
| 	print("The universe is functional!") | ||||
| 	print("The universe is functional!"); | ||||
| } | ||||
| unless | ||||
| { | ||||
| 	print("WHAT, HOW") | ||||
| 	print("WHAT, HOW"); | ||||
| } | ||||
| @@ -2,7 +2,7 @@ depend "io.pla" | ||||
| depend "string.pla" | ||||
|  | ||||
| add = Func(a: Int, b: Int): Int { | ||||
| 	return a + b | ||||
| 	return a + b; | ||||
| } | ||||
|  | ||||
| print(String(add(1, 3))) | ||||
| print(String(add(1, 3))); | ||||
| @@ -1,2 +1,2 @@ | ||||
| depend "io.pla" | ||||
| print("Hello, World!") | ||||
| print("Hello, World!"); | ||||
| @@ -1,6 +0,0 @@ | ||||
| 123 | ||||
| 0.456 | ||||
| [] | ||||
| {} | ||||
| (1 + 3 * 2 ^ 4) % 2 | ||||
| 2 - 1 | ||||
| @@ -1 +0,0 @@ | ||||
| (5 + 5) * 3 + 2 | ||||
							
								
								
									
										2
									
								
								tests/test.pla
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tests/test.pla
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| a: Float = 1.23; | ||||
| b: Int = 456; | ||||
| @@ -14,6 +14,6 @@ struct Person { | ||||
|  | ||||
| speak = Func(sentence: String): Nil { | ||||
| 	print(sentence) | ||||
| }  | ||||
| } | ||||
|  | ||||
| max: Person = {"Max", 17, } | ||||
| max: Person = {"Max", 17, speak, Gender.male}; | ||||
| @@ -1,16 +1,16 @@ | ||||
| depend "string.pla" | ||||
| depend "io.h" | ||||
|  | ||||
| myInt: Int = 123 | ||||
| myDecimal: Float = 0.456 | ||||
| myBoolean: Bool = true | ||||
| myString: String = "Hello!\n" | ||||
| myList: List = [1, "hi", true, [1, 2, 3], 0.789] | ||||
| myInt: Int = 123; | ||||
| myDecimal: Float = 0.456; | ||||
| myBoolean: Bool = true; | ||||
| myString: String = "Hello!\n"; | ||||
| myList: List = [1, "hi", true, [1, 2, 3], 0.789]; | ||||
|  | ||||
| MY_CONSTANT: Const(String) = "foo bar" | ||||
| MY_CONSTANT: Const(String) = "foo bar"; | ||||
|  | ||||
| print(String(myInt)) | ||||
| print(String(myDecimal)) | ||||
| print(String(myBoolean)) | ||||
| print(myString) | ||||
| print(String(myList)) | ||||
| print(String(myInt)); | ||||
| print(String(myDecimal)); | ||||
| print(String(myBoolean)); | ||||
| print(myString); | ||||
| print(String(myList)); | ||||
		Reference in New Issue
	
	Block a user
	 SpookyDervish
					SpookyDervish