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

308 lines
9.1 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.
- \`:\` **Declaration**: Binds a name in the current scope.
- \`=\` **Assignment**: Reassigns the value of an existing name.
\`\`\`javascript
version: 1.0 // Declaration and initialization
version = 1.1 // Assignment
\`\`\`
## 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
player: {
name: "Orion" // Public property
#hp: 100 // Private property
}
_(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 // Mutates parent's private state
}
get: {
value // The 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]
firstPrime: primes[0] // Access
primes[0] = 1 // Mutation
_(primes) // [1, 3, 5, 7]
\`\`\`
## 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 // Condition becomes false
}
// 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
+ "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
// Last expression is an assignment, so 'this' is returned
add: (n) { total = total + n }
sub: (n) { total = total - n }
// Last expression is a value, which is returned
get: { ^ 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>