Files
hi-language.github.io/index.html

317 lines
9.7 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hi: A Symbolic Programming Language</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
<!-- Markdown & Highlighting Styles -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@5.8.1/github-markdown-light.min.css"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/github.min.css"/>
<!-- Lucide Icons -->
<script src="https://unpkg.com/lucide@latest"></script>
<!-- Markdown-it and Highlight.js -->
<script src="https://cdn.jsdelivr.net/npm/markdown-it@14.1.0/dist/markdown-it.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/highlight.min.js"></script>
<style>
body {
font-family: 'Poppins', sans-serif;
background-color: #f9fafb; /* bg-gray-50 */
}
.markdown-body {
font-size: 14px;
line-height: 1.7;
background-color: transparent;
}
.markdown-body h1, .markdown-body h2, .markdown-body h3 {
font-family: 'Poppins', sans-serif;
font-weight: 600;
border-bottom-color: #e5e7eb; /* border-gray-200 */
}
.markdown-body pre {
background-color: #ffffff;
border: 1px solid #e5e7eb;
border-radius: 0.75rem;
padding: 1rem;
overflow-x: auto;
}
.markdown-body code {
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
font-variant-ligatures: none;
}
:not(pre) > code {
font-size: 85%;
padding: .2em .4em;
margin: 0;
border-radius: 6px;
background-color: rgba(175, 184, 193, 0.2);
}
.hi-button {
font-family: 'JetBrains Mono', monospace;
}
</style>
</head>
<body class="text-gray-900 selection:bg-cyan-400/20">
<header class="sticky top-0 z-20 bg-white/80 backdrop-blur-sm border-b border-gray-200">
<div class="mx-auto w-full max-w-4xl px-4 py-3 flex items-center justify-center">
<button class="hi-button text-2xl font-bold text-gray-900 px-6 py-2 rounded-lg cursor-default transition-all duration-300 hover:bg-gray-100">
Hi
</button>
</div>
</header>
<main class="w-full min-h-screen flex flex-col items-center p-4 sm:p-8">
<div id="content" class="markdown-body w-full max-w-4xl">
<!-- Markdown content will be rendered here -->
</div>
</main>
<script>
const markdownContent = `
# A corely symbolic language
**Hi** is a programming language inspired by JavaScript, designed with a symbolic core to be more universal, AI-friendly, and conducive to code golfing. The syntax prioritizes symbols over keywords.
The underscore \`_\` is the global output function.
\`\`\`javascript
_("Hi world")
\`\`\`
## Declaration and Assignment
Variable lifecycle is split into two distinct symbolic operations. A semicolon \`;\` can be used to separate expressions on a single line.
- \`:\` **Declaration**: Binds a name in the current scope.
- \`=\` **Assignment**: Reassigns the value of an existing name.
\`\`\`javascript
version: 1.0; version = 1.1
\`\`\`
## The Block: A Unified Structure
The \`{}\` syntax creates a **Block**, the foundational structure in Hi. A Block is a container for both properties (state) and executable code (behavior), functioning simultaneously as a callable object and a stateful function.
### Function Block
A Block with only executable code is a function.
\`\`\`javascript
sayHi: { _("Hi") }
sayHi() // Invokes the block
\`\`\`
### Object Block
A Block with named properties is an object. A \`#\` prefix denotes a private property, inaccessible from outside the block's scope.
\`\`\`javascript
// A Block can be defined on one line using ';'
player: { name: "Orion"; #hp: 100 }
_(player.name) // "Orion"
\`\`\`
### Hybrid Block
Blocks can contain both state and methods. Inner blocks lexically inherit the scope of their parent, allowing them to access and mutate the parent's private state. This provides true encapsulation without classes.
\`\`\`javascript
counter: {
#value: 0
inc: { value = value + 1 } // Concise one-liner methods
get: { value } // Last expression is implicitly returned
}
counter.inc()
_(counter.get()) // Prints 1
\`\`\`
### Blocks with Parameters
\`\`\`javascript
greet: (name) { _("Hi, " + name) }
greet("Orion")
\`\`\`
## Arrow Blocks
To enhance conciseness, Hi adopts the \`=>\` ("fat arrow") from JavaScript for single-expression blocks. This provides a shorthand for a block that immediately returns the value of its expression, perfect for callbacks and functional patterns.
It's a direct replacement for \`(params) { ^ expression }\`.
\`\`\`javascript
// Standard block
add: (a, b) { ^ a + b }
// Equivalent Arrow Block
add: (a, b) => a + b
// Useful for functional helpers
numbers: [1, 2, 3]
doubled: numbers.map((n) => n * 2)
_(doubled) // [2, 4, 6]
\`\`\`
## Booleans and Equality
Hi dispenses with boolean keywords in favor of canonical numeric values for truthiness.
- \`0\` is **falsy** (the canonical false).
- \`!0\` is **truthy** (the canonical true, representing a logical NOT 0).
- \`-0\` represents null/undefined values.
- All other numbers, and any non-empty string, block, or array are "truthy".
- The \`==\` operator performs strict equality comparison (equivalent to JavaScript's \`===\`).
## Conditional Expressions
All conditional logic is handled by a single ternary expression structure, which always returns a value.
\`\`\`javascript
// if
(1 < 2) ? { _("True") }
// if / else
result: (1 > 2) ? { "A" } : { "B" } // result is "B"
// if / else if / else
score: 75
grade: (score >= 90) ? { "A" }
: (score >= 80) ? { "B" }
: (score >= 70) ? { "C" }
: { "D" } // The final else case
_(grade) // Prints "C"
\`\`\`
## Data Structures
### Arrays
Arrays are 0-indexed lists of values.
\`\`\`javascript
primes: [2, 3, 5, 7]
primes[0] = 1 // Mutation
_(primes) // [1, 3, 5, 7]
\`\`\`
## Destructuring
Destructuring provides an expressive way to extract data from Blocks and Arrays. The extraction operator \`->\` is used to unpack values, mirroring its use in module imports.
- \`source -> { pattern }\`: Extracts properties from a Block.
- \`source -> [ pattern ]\`: Extracts elements from an Array.
- \`prop -> alias\`: The same operator is used within the pattern for aliasing.
\`\`\`javascript
// Setup
user: { name: "Zeta"; role: "Admin"; id: 101 }
coords: [10, -5, 8]
// Extract 'name' and 'role' from the user block
user -> { name, role }
_(name) // "Zeta"
// Extract 'id' and alias it to 'userID'
user -> { id -> userID }
_(userID) // 101
// Extract first two elements from the array
coords -> [x, y]
_(y) // -5
\`\`\`
## Repetition
Loops are initiated with the \`*\` operator following a standard three-part condition or a simple boolean expression.
- \`>>\` is used for **continue**.
- \`^\` is used for **return/break**.
\`\`\`javascript
// for-style loop
(i: 0; i < 3; i = i + 1) * {
_("Iteration: " + i)
}
// while-style loop
active: !0
(active) * {
_("Looping..."); active = 0
}
// Loop Control
(i: 0; i < 10; i = i + 1) * {
(i == 5) ? { ^ } // Break at 5
_("i is " + i)
}
// Prints i is 0 through 4
\`\`\`
## Imports
Modules are imported using the \`+\` and \`->\` operators. This allows for destructuring and aliasing of imported members.
\`\`\`javascript
// Import 'block1' and 'block2' (as 'alias2') from a module
+ "npm://hi-lang@0.1/path/file.hi" -> { block1, block2 -> alias2 }
block1()
alias2("some value")
\`\`\`
## Method Chaining
A Block's return behavior is designed for fluency. It implicitly returns the value of its last expression. If the last expression does not yield a value (such as an assignment), the Block returns itself (\`this\`) by default, enabling method chaining. The \`^\` symbol is used for an explicit or early return from any point in the Block.
\`\`\`javascript
calculator: {
#total: 0
add: (n) { total = total + n } // Implicitly returns 'this'
sub: (n) { total = total - n } // Implicitly returns 'this'
get: { ^ total } // Explicitly returns the total
}
// .add() and .sub() return the calculator, allowing the chain
result: calculator.add(10).sub(4).get()
_(result) // Prints 6
\`\`\`
---
<p class="text-sm text-gray-600">Hi is in early development. The syntax and features are subject to change.</p>
`;
document.addEventListener('DOMContentLoaded', () => {
const md = window.markdownit({
html: true,
linkify: true,
typographer: true,
highlight: (str, lang) => {
if (lang && hljs.getLanguage(lang)) {
try {
return `<pre class="hljs"><code>${hljs.highlight(str, { language: lang, ignoreIllegals: true }).value}</code></pre>`;
} catch (__) {}
}
return `<pre class="hljs"><code>${md.utils.escapeHtml(str)}</code></pre>`;
}
});
document.getElementById('content').innerHTML = md.render(markdownContent);
lucide.createIcons();
});
</script>
</body>
</html>